如何在不连接数据库的情况下在 nestjs 和 typeorm 中编写单元测试
How to write unit test in nestjs and typeorm without connecting to db
我不确定如何在不连接到数据库的情况下在 nestjs 和 typeorm 中实现单元测试。我尝试了很多技术,但似乎都没有用。
我的模块看起来像这样。
import { HttpModule, Module } from '@nestjs/common'
import moment from 'moment';
import config from '@app/config'
import { OrdersService } from './services/order.service'
import { FraudOrderChecksService } from './services/fraud-order-checks.service'
import { FraudOrderChecksController } from './controllers/fraud-order-checks.controller'
import { HealthcheckController } from './controllers/healthcheck.controller';
import { TypeOrmModule } from '@nestjs/typeorm'
import { ormconfig } from './entities/ormconfig'
@Module({
imports: [
SharedModule,
HttpModule,
LoggerModule,
ConfigModule.forRoot(config),
TypeOrmModule.forRoot(ormconfig.luminskin as any),
TypeOrmModule.forRoot(ormconfig.meridian as any),
TypeOrmModule.forFeature([...ormconfig.luminskin.entities], 'luminskin'),
TypeOrmModule.forFeature([...ormconfig.meridian.entities], 'meridian'),
...
],
controllers: [
MyController,
...
],
providers: [
...
],
})
export class AppModule { }
我在测试中导入根模块
beforeEach(async () => {
jest.clearAllMocks();
const module: TestingModule = await Test.createTestingModule({
imports: [InternalModule]
}).compile();
...
});
当我尝试 运行 我的单元测试时,我得到
[Nest] 93196 - 06/04/2021, 17:43:50 [ExceptionHandler] Unable to connect to the database (mydb). Retrying (1)...
AlreadyHasActiveConnectionError: Cannot create a new connection named "connectionname", because connection with such name already exist and it now has an active connection session.
如何将连接与根模块解耦,以便仅在需要时 运行。其实cleaner technic也会被接受
您不想对模块进行单元测试,而是希望对模块的各个组件进行单独的单元测试。
尽管您可以 创建一个 TestModule 并像上面那样简单地导入您的模块,但我只会在模块包含单个组件时才考虑这样做(即使那样我也不会因为我认为这不是很好的做法)。
您带入测试的组件越多:
- 您需要管理的活动部件越多
- 你要嘲笑的越多
- 单元及其测试的便携性越差
- 你摄入的阿司匹林越多,尝试解决每次修改其父模块时发生的自我诱发的头痛
Nests TestingModule 使您能够以隔离测试您的组件 所需的最低限度“装配”一个独立模块。它简化了您的测试设置和模拟 creation/management.
始终尝试将单元测试视为一个独立的、独立的过程。尽可能限制范围和依赖性,以使测试尽可能有效和简单。
这是我对服务进行单元测试时所采用的方法示例,我模拟了它的依赖项:
// app.service.spec.ts
describe('Testing app.service', () => {
let module: TestingModule;
let service: AppService;
// mock out providers the service depends on
const mockProviders = [
{
provide: ConfigService,
useValue: {
get: jest.fn().mockReturnValue('Mock!'),
},
},
];
beforeAll(async () => {
// build up testing module
module = await Test.createTestingModule({
imports: [],
providers: [...mockProviders, AppService],
})
.compile()
.catch((err) => {
// Helps catch ninja like errors from compilation
console.error(err);
throw err;
});
service = module.get<AppService>(AppService);
});
it('Should return: Hello Mock!', async () => {
const response = service.getHello();
expect(response).toEqual('Hello Mock');
});
});
我尝试将所有业务逻辑(尽可能)保留在服务中,让控制器保持轻便,通常保留用于 e2e and/or 集成测试。
这不是唯一(甚至可能不是“最佳”)方法,但它可以帮助我更加专注于测试和服务。
我不确定如何在不连接到数据库的情况下在 nestjs 和 typeorm 中实现单元测试。我尝试了很多技术,但似乎都没有用。
我的模块看起来像这样。
import { HttpModule, Module } from '@nestjs/common'
import moment from 'moment';
import config from '@app/config'
import { OrdersService } from './services/order.service'
import { FraudOrderChecksService } from './services/fraud-order-checks.service'
import { FraudOrderChecksController } from './controllers/fraud-order-checks.controller'
import { HealthcheckController } from './controllers/healthcheck.controller';
import { TypeOrmModule } from '@nestjs/typeorm'
import { ormconfig } from './entities/ormconfig'
@Module({
imports: [
SharedModule,
HttpModule,
LoggerModule,
ConfigModule.forRoot(config),
TypeOrmModule.forRoot(ormconfig.luminskin as any),
TypeOrmModule.forRoot(ormconfig.meridian as any),
TypeOrmModule.forFeature([...ormconfig.luminskin.entities], 'luminskin'),
TypeOrmModule.forFeature([...ormconfig.meridian.entities], 'meridian'),
...
],
controllers: [
MyController,
...
],
providers: [
...
],
})
export class AppModule { }
我在测试中导入根模块
beforeEach(async () => {
jest.clearAllMocks();
const module: TestingModule = await Test.createTestingModule({
imports: [InternalModule]
}).compile();
...
});
当我尝试 运行 我的单元测试时,我得到
[Nest] 93196 - 06/04/2021, 17:43:50 [ExceptionHandler] Unable to connect to the database (mydb). Retrying (1)...
AlreadyHasActiveConnectionError: Cannot create a new connection named "connectionname", because connection with such name already exist and it now has an active connection session.
如何将连接与根模块解耦,以便仅在需要时 运行。其实cleaner technic也会被接受
您不想对模块进行单元测试,而是希望对模块的各个组件进行单独的单元测试。
尽管您可以 创建一个 TestModule 并像上面那样简单地导入您的模块,但我只会在模块包含单个组件时才考虑这样做(即使那样我也不会因为我认为这不是很好的做法)。
您带入测试的组件越多:
- 您需要管理的活动部件越多
- 你要嘲笑的越多
- 单元及其测试的便携性越差
- 你摄入的阿司匹林越多,尝试解决每次修改其父模块时发生的自我诱发的头痛
Nests TestingModule 使您能够以隔离测试您的组件 所需的最低限度“装配”一个独立模块。它简化了您的测试设置和模拟 creation/management.
始终尝试将单元测试视为一个独立的、独立的过程。尽可能限制范围和依赖性,以使测试尽可能有效和简单。
这是我对服务进行单元测试时所采用的方法示例,我模拟了它的依赖项:
// app.service.spec.ts
describe('Testing app.service', () => {
let module: TestingModule;
let service: AppService;
// mock out providers the service depends on
const mockProviders = [
{
provide: ConfigService,
useValue: {
get: jest.fn().mockReturnValue('Mock!'),
},
},
];
beforeAll(async () => {
// build up testing module
module = await Test.createTestingModule({
imports: [],
providers: [...mockProviders, AppService],
})
.compile()
.catch((err) => {
// Helps catch ninja like errors from compilation
console.error(err);
throw err;
});
service = module.get<AppService>(AppService);
});
it('Should return: Hello Mock!', async () => {
const response = service.getHello();
expect(response).toEqual('Hello Mock');
});
});
我尝试将所有业务逻辑(尽可能)保留在服务中,让控制器保持轻便,通常保留用于 e2e and/or 集成测试。
这不是唯一(甚至可能不是“最佳”)方法,但它可以帮助我更加专注于测试和服务。