node.js - 使用 TypeORM 進行整合測試
我正在透過 Supertest 向我的開發伺服器發送請求來進行整合測試。但我在如何將資料放入資料庫時遇到麻煩。例如,在執行 GET 測試之前,我想將資料插入資料庫。但我甚至無法從 TypeORM 獲取連線:
ConnectionNotFoundError: Connection "default" was not found.
即使我能從 TypeORM 獲得連接,我如何在交易中包裹測試,並在測試完成後回滾交易,以確保整合測試不會影響真實資料庫。
基本上,有沒有任何套件類似於 Rails 的 factory_bot?
describe("Templates", (): void => {
describe("GET /api/v1/templates/{templateHash}", (): void => {
let template: Template;
beforeEach(
async (): Promise<void> => {
let templateService: TemplateService = new TemplateService();
let connection: Connection = getConnection("default");
template = new Template(Buffer.from(faker.random.words()), faker.random.uuid(), faker.system.fileName());
await templateService.create(connection, template);
},
);
it("should return a template", (done): void => {
request(config.devEnvEndpoint)
.get(`api/v1/templates/${template.templateHash}`)
.set("Accept", "application/json")
.expect(200)
.end((err, response): void => {
console.log(response);
done();
});
});
});
});
答案#1
看起來 typeorm 沒有讀取到你的配置。我建議使用 ormconfig.json 文件,並擁有兩個資料庫配置——一個用於開發,一個用於測試。
擁有兩個資料庫後,你就不需要擔心交易,並且可以在測試之間刪除資料庫。我想交易會更快,但這真的取決於你的使用情況(我注意到在進行大量 connection.synchronize() 呼叫時,測試變得慢得多)。
那麼你可以使用環境變數來決定要實例化哪個連接:
// db.ts
import { Connection, createConnection } from 'typeorm'
let connection: Connection | null = null
export async function getConnection() {
if (connection) {
return connection;
}
// DATABASE_CONFIG can be 'development' or 'test'
// and should correspond to the connection names
// in the ormconfig.json file
connection = await createConnection(process.env.DATABASE_CONFIG);
return connection;
}
export async function closeConnection() {
await connection?.close();
}
然後你可以設定環境變數並運行你的測試:
// DATABASE_CONFIG=test yarn test
import { getConnection, closeConnection } from './db'
let connection: Connection;
beforeAll(async () => {
connection = await getConnection();
});
beforeEach(async () => {
// Drop everything and recreate db
await connection.synchronize(true);
});
afterAll(async () => {
await closeConnection();
});
it('should create a connection', () => {
expect(connection).toBeDefined();
})
