我有2个db,一个用于开发,一个用于测试。我想在运行jest test时连接到测试数据库,我设置了2个.env
配置,开发使用.env
,测试使用.env.test
。但是单元测试不能通过connection.ts
连接数据库。
更新目录模式
app
├── .env
├── .env.test
├── loadEnv.ts
├── package.json
├── ormconfig-cli.ts
├── src
│ ├── connection.ts
│ ├── app.module.ts
│ ├── user
│ │ ├── entities
│ │ │ └── user.entity.ts
│ │ ├── user.module.ts
│ │ ├── user.resolver.spec.ts
│ │ ├── user.resolver.ts
│ │ ├── user.service.spec.ts
│ │ └── user.service.ts
字符串
更新连接错误
无法创建连接,getConnection().isConnected = false
和getConnection('test')
(或'default'
)抛出“未找到连接”错误。
//connection.ts
import { loadEnv } from '../loadEnv';
import connectionOptions from '../ormconfig-cli';
loadEnv();
async create(): Promise<Connection> {
const connOptions: ConnectionOptions = connectionOptions.find(option => option.name == process.env.NODE_ENV);
return await createConnection({ ...connOptions, name: 'default' });
},
型
下面是设置:
// package.json
{
...,
"scripts": {
...,
"test": "NODE_ENV=test jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
}, {...},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"clearMocks": true
}
}
// .env.test
NODE_ENV=test
TYPEORM_HOST=localhost
TYPEORM_PORT=5432
TYPEORM_USERNAME=root
TYPEORM_PASSWORD=test
TYPEORM_DATABASE=test
# TEST_DATABASE="postgres://root:test@localhost:5432/test jest"
// loadEnv.ts
import * as dotenv from 'dotenv';
export const loadEnv = () => {
const loadFile = () => {
if (process.env.NODE_ENV === 'test') return '.env.test';
return '.env';
};
return dotenv.config({
path: loadFile(),
});
};
// ormconfig.ts
import { loadEnv } from './loadEnv';
import { ConnectionOptions } from 'typeorm';
loadEnv();
const SnakeNamingStrategy = require('typeorm-naming-strategies')
.SnakeNamingStrategy;
const connectionOptions: ConnectionOptions[] = [
{
name: 'development',
type: 'postgres',
host: String(process.env.TYPEORM_HOST),
port: Number(process.env.TYPEORM_PORT),
username: String(process.env.TYPEORM_USERNAME),
password: String(process.env.TYPEORM_PASSWORD),
database: String(process.env.TYPEORM_DATABASE),
synchronize: false,
logging: true,
cli: {
migrationsDir: 'src/migrations',
},
namingStrategy: new SnakeNamingStrategy(),
entities: ['dist/**/*.entity{.ts,.js}'],
migrations: ['dist/src/migrations/*.{js,ts}'],
migrationsTransactionMode: 'each',
},
{
name: 'test',
type: 'postgres',
host: String(process.env.TYPEORM_HOST),
port: Number(process.env.TYPEORM_PORT),
username: String(process.env.TYPEORM_USERNAME),
password: String(process.env.TYPEORM_PASSWORD),
database: String(process.env.TYPEORM_DATABASE),
synchronize: false,
dropSchema: true,
logging: true,
cli: {
migrationsDir: 'src/migrations',
},
namingStrategy: new SnakeNamingStrategy(),
entities: ['dist/**/*.entity{.ts,.js}'],
migrations: ['dist/src/migrations/*.{js,ts}'],
migrationsTransactionMode: 'each',
},
];
export = connectionOptions;
// app.module.ts
@Module({
imports: [
TypeOrmModule.forRoot({
name: 'development',
type: 'postgres',
host: process.env.TYPEORM_HOST,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
migrationsRun: true,
synchronize: false,
migrationsTransactionMode: 'each',
migrations: ['dist/src/migrations/*.{js,ts}'],
namingStrategy: new SnakeNamingStrategy(),
autoLoadEntities: true,
}),
TypeOrmModule.forRoot({
name: 'test',
type: 'postgres',
host: process.env.TYPEORM_HOST,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
logging: false,
dropSchema: true,
migrationsRun: true,
synchronize: false,
migrationsTransactionMode: 'each',
migrations: ['dist/src/migrations/*.{js,ts}'],
namingStrategy: new SnakeNamingStrategy(),
autoLoadEntities: true,
}),
...,
],
})
export class AppModule {}
// connection.ts
import { Connection, createConnection, getConnection, getConnectionOptions } from 'typeorm';
import { loadEnv } from '../loadEnv';
loadEnv();
export const connection = {
async create(): Promise<Connection> {
const connectionOptions = await getConnectionOptions(process.env.NODE_ENV);
return await createConnection({ ...connectionOptions, name: 'default' });
},
async close() {
await getConnection().close();
},
async clear() {
const connection = getConnection();
const entities = connection.entityMetadatas;
entities.forEach(async (entity) => {
const repo = connection.getRepository(entity.name);
await repo.query(`DELETE FROM ${entity.tableName}`);
});
},
async isConnected() {
return getConnection().isConnected;
},
};
如果运行npm test src/test/user.service.spec.ts
,将得到错误:在任何orm配置文件中找不到连接选项。日志console.log("connection.isConnected(): ", connection.isConnected());
获取错误:ConnectionNotFoundError:未找到连接“default”。
下面是测试用例:
import { getConnection, Repository } from 'typeorm';
import { createMock } from '@golevelup/nestjs-testing';
import { User } from '../user/user.entity';
import { connection } from '../connection';
describe('UserService', () => {
beforeAll(async () => {
await connection.create();
});
afterAll(async () => {
await connection.clear();
await connection.close();
});
describe('beforeAll connection.create()', async () => {
const repo = createMock<Repository<User>>();
it('should create user', function() {
console.log('env: ', process.env.NODE_ENV); // env: test
console.log("connection.isConnected(): ", connection.isConnected());
const user = {
id: 'uuid',
avatar: 'avatar',
name: 'user A',
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: new Date(),
};
console.log(user);
repo.create(user);
repo.find.mockResolvedValue([user]);
});
});
});
型
如果不使用connection.create()
连接,则connection.isConnected()
将为true。
...
beforeAll(async () => {
await createConnection({
type: "postgres",
host: "localhost",
port: 5432,
username: "root",
password: "test",
database: "test",
logging: false,
});
});
...
型
我怎样才能更新我的设置和连接数据库通过我的测试配置?
1条答案
按热度按时间j91ykkif1#
尝试使用TypeORM的ConfigModule。它会以一种更干净的方式做这些事情。此外,即使使用配置模块,您也需要在特定的测试文件中指定测试配置(.env)文件的路径。
在
beforeEach
块内的.spec.ts文件中使用以下代码字符串
有关详细的实现,请参阅文档https://docs.nestjs.com/techniques/configuration