Ene*_*neh 5 jestjs typeorm ts-jest
我有 2 个 db,一个用于开发,一个用于测试。我想在运行 jest test 时连接到测试数据库,我设置了 2 个.env配置,开发使用.env,测试使用.env.test。但单元测试无法通过connection.ts.
app\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env.test\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 loadEnv.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ormconfig-cli.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 connection.ts\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.module.ts\n\xe2\x94\x82\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user\n\xe2\x94\x82 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 entities\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 user.entity.ts\n\xe2\x94\x82\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.module.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.resolver.spec.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.resolver.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.service.spec.ts\n\xe2\x94\x82\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 user.service.ts\nRun Code Online (Sandbox Code Playgroud)\n无法创建连接,getConnection().isConnected = false并且\n getConnection(\'test\')(或\'default\')抛出“未找到连接”。错误。
app\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env.test\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 loadEnv.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ormconfig-cli.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 connection.ts\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.module.ts\n\xe2\x94\x82\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user\n\xe2\x94\x82 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 entities\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 user.entity.ts\n\xe2\x94\x82\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.module.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.resolver.spec.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.resolver.ts\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 user.service.spec.ts\n\xe2\x94\x82\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xc2\xa0\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 user.service.ts\nRun Code Online (Sandbox Code Playgroud)\n这是设置:
\n//connection.ts\n\nimport { loadEnv } from \'../loadEnv\';\nimport connectionOptions from \'../ormconfig-cli\';\nloadEnv();\n\n async create(): Promise<Connection> {\n const connOptions: ConnectionOptions = connectionOptions.find(option => option.name == process.env.NODE_ENV);\n return await createConnection({ ...connOptions, name: \'default\' });\n },\nRun Code Online (Sandbox Code Playgroud)\n// .env.test\n\nNODE_ENV=test\n\nTYPEORM_HOST=localhost\nTYPEORM_PORT=5432\nTYPEORM_USERNAME=root\nTYPEORM_PASSWORD=test\nTYPEORM_DATABASE=test\n\n# TEST_DATABASE="postgres://root:test@localhost:5432/test jest"\nRun Code Online (Sandbox Code Playgroud)\n// package.json\n\n{\n ...,\n "scripts": {\n ...,\n "test": "NODE_ENV=test jest",\n "test:watch": "jest --watch",\n "test:cov": "jest --coverage",\n "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",\n "test:e2e": "jest --config ./test/jest-e2e.json",\n }, {...},\n "jest": {\n "moduleFileExtensions": [\n "js",\n "json",\n "ts"\n ],\n "rootDir": "src",\n "testRegex": ".*\\\\.spec\\\\.ts$",\n "transform": {\n "^.+\\\\.(t|j)s$": "ts-jest"\n },\n "collectCoverageFrom": [\n "**/*.(t|j)s"\n ],\n "coverageDirectory": "../coverage",\n "testEnvironment": "node",\n "clearMocks": true\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n// .env.test\n\nNODE_ENV=test\n\nTYPEORM_HOST=localhost\nTYPEORM_PORT=5432\nTYPEORM_USERNAME=root\nTYPEORM_PASSWORD=test\nTYPEORM_DATABASE=test\n\n# TEST_DATABASE="postgres://root:test@localhost:5432/test jest"\nRun Code Online (Sandbox Code Playgroud)\n// loadEnv.ts\n\nimport * as dotenv from \'dotenv\';\n\nexport const loadEnv = () => {\n const loadFile = () => {\n if (process.env.NODE_ENV === \'test\') return \'.env.test\';\n return \'.env\';\n };\n\n return dotenv.config({\n path: loadFile(),\n });\n};\nRun Code Online (Sandbox Code Playgroud)\n// ormconfig.ts\n\nimport { loadEnv } from \'./loadEnv\';\nimport { ConnectionOptions } from \'typeorm\';\n\nloadEnv();\n\nconst SnakeNamingStrategy = require(\'typeorm-naming-strategies\')\n .SnakeNamingStrategy;\n\nconst connectionOptions: ConnectionOptions[] = [\n {\n name: \'development\',\n type: \'postgres\',\n host: String(process.env.TYPEORM_HOST),\n port: Number(process.env.TYPEORM_PORT),\n username: String(process.env.TYPEORM_USERNAME),\n password: String(process.env.TYPEORM_PASSWORD),\n database: String(process.env.TYPEORM_DATABASE),\n synchronize: false,\n logging: true,\n cli: {\n migrationsDir: \'src/migrations\',\n },\n namingStrategy: new SnakeNamingStrategy(),\n entities: [\'dist/**/*.entity{.ts,.js}\'],\n migrations: [\'dist/src/migrations/*.{js,ts}\'],\n migrationsTransactionMode: \'each\',\n },\n {\n name: \'test\',\n type: \'postgres\',\n host: String(process.env.TYPEORM_HOST),\n port: Number(process.env.TYPEORM_PORT),\n username: String(process.env.TYPEORM_USERNAME),\n password: String(process.env.TYPEORM_PASSWORD),\n database: String(process.env.TYPEORM_DATABASE),\n synchronize: false,\n dropSchema: true,\n logging: true,\n cli: {\n migrationsDir: \'src/migrations\',\n },\n namingStrategy: new SnakeNamingStrategy(),\n entities: [\'dist/**/*.entity{.ts,.js}\'],\n migrations: [\'dist/src/migrations/*.{js,ts}\'],\n migrationsTransactionMode: \'each\',\n },\n];\n\nexport = connectionOptions;\nRun Code Online (Sandbox Code Playgroud)\n如果运行npm test src/test/user.service.spec.ts,会得到错误:No connection options were found in any orm configuration files.\n日志console.log("connection.isConnected(): ", connection.isConnected());错误:\nConnectionNotFoundError:未找到连接“默认”。
这是测试用例:
\n// app.module.ts\n\n@Module({\n imports: [\n TypeOrmModule.forRoot({\n name: \'development\',\n type: \'postgres\',\n host: process.env.TYPEORM_HOST,\n username: process.env.TYPEORM_USERNAME,\n password: process.env.TYPEORM_PASSWORD,\n database: process.env.TYPEORM_DATABASE,\n migrationsRun: true,\n synchronize: false,\n migrationsTransactionMode: \'each\',\n migrations: [\'dist/src/migrations/*.{js,ts}\'],\n namingStrategy: new SnakeNamingStrategy(),\n autoLoadEntities: true,\n }),\n TypeOrmModule.forRoot({\n name: \'test\',\n type: \'postgres\',\n host: process.env.TYPEORM_HOST,\n username: process.env.TYPEORM_USERNAME,\n password: process.env.TYPEORM_PASSWORD,\n database: process.env.TYPEORM_DATABASE,\n logging: false,\n dropSchema: true,\n migrationsRun: true,\n synchronize: false,\n migrationsTransactionMode: \'each\',\n migrations: [\'dist/src/migrations/*.{js,ts}\'],\n namingStrategy: new SnakeNamingStrategy(),\n autoLoadEntities: true,\n }),\n ...,\n ],\n})\nexport class AppModule {}\nRun Code Online (Sandbox Code Playgroud)\n如果不使用connection.create()连接,connection.isConnected()则会如此。
// connection.ts\n\nimport { Connection, createConnection, getConnection, getConnectionOptions } from \'typeorm\';\nimport { loadEnv } from \'../loadEnv\';\n\nloadEnv();\n\nexport const connection = {\n async create(): Promise<Connection> {\n const connectionOptions = await getConnectionOptions(process.env.NODE_ENV);\n return await createConnection({ ...connectionOptions, name: \'default\' });\n },\n\n async close() {\n await getConnection().close();\n },\n\n async clear() {\n const connection = getConnection();\n const entities = connection.entityMetadatas;\n\n entities.forEach(async (entity) => {\n const repo = connection.getRepository(entity.name);\n await repo.query(`DELETE FROM ${entity.tableName}`);\n });\n },\n\n async isConnected() {\n return getConnection().isConnected;\n },\n};\n\nRun Code Online (Sandbox Code Playgroud)\n如何通过测试配置更新我的设置并连接数据库?
\n小智 0
尝试使用ConfigModule的TypeORM. 它将以更干净的方式完成这些工作。此外,即使在使用模块时,您也需要在特定测试文件中config指定测试文件的路径。config(.env)
beforeEach在块内的 .spec.ts 文件中使用以下代码
const module: TestingModule = Test.createTestingModule({[
imports: [
ConfigModule.forRoot({
encFilePath: '<your env file path with reference to the project root>'
})
],
providers: []
...
]}).compile()
Run Code Online (Sandbox Code Playgroud)
详细实现请参考文档https://docs.nestjs.com/techniques/configuration