【发布时间】:2021-08-03 21:28:18
【问题描述】:
我目前正在对我的 NestJS 服务进行单元测试。我的实体称为“用户”,我建立了一个基本服务,允许我与 MS SQL 服务器交互,并在我的控制器中建立 GET 和 POST 端点。
虽然我能够模拟服务中使用的 Repository,但我无法在必须调用 getConection() 的方法中建立模拟 getConnection。
当我尝试使用 npm run test:watch 进行单元测试时,我收到了 ConnectionNotFoundError: Connection "default" was not found. 的错误,我已经研究过(实际上,从How to stub EntityManager and Connection in TypeORM with Jest 中提取了很多内容),但这篇文章似乎没有详细说明没有成立,这是我的问题。
无论如何,这是我的相关部分的服务:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { getConnection, Repository } from "typeorm";
import {User} from '../entities/user.entity';
@Injectable()
export class ServiceName {
constructor(@InjectRepository(User) private usersRepository: Repository<User>) {}
// Creating and inserting a new user into the database table using Repository
// unit testing for this one works fine
async createUserRepository(user: User): Promise<User> {
const newUser = this.usersRepository.create(user);
return await this.usersRepository.save(newUser);
}
// Creating and inserting a new user into the database table using QueryBuilder and getConnection
// unit testing for this one does not work so well
async createUserQueryBuilder(user: User): Promise<User> {
await getConnection()
.createQueryBuilder()
.insert()
.into(User)
.values([
user,
])
.execute();
return user;
}
这是我用于单元测试的 spec.ts 文件:
import { Test, TestingModule } from '@nestjs/testing';
import { ServiceName } from './app_codes_rms_area.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from '../entities/user.entity';
import { Connection, Repository } from 'typeorm';
describe('service tests', () => {
const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({
create: jest.fn(),
save: jest.fn(),
// other functions
}));
const mockConnectionFactory = jest.fn(() => ({
getConnection: jest.fn().mockReturnValue({
createQueryBuilder: jest.fn().mockReturnThis(),
getMany: jest.fn().mockReturnValue(allUsers),
insert: jest.fn().mockReturnThis(),
into: jest.fn().mockReturnThis(),
values: jest.fn().mockReturnThis(),
execute: jest.fn().mockReturnValue(user),
})
}));
let service: ServiceName;
let mockRepository: MockType<Repository<User>>;
let mockConnection: Connection;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ServiceName,
{
provide: getRepositoryToken(User), // a User Repository is injected to the service
useFactory: repositoryMockFactory, // using factory ensures that a new mock is used for every test
},
{
provide: Connection,
useFactory: mockConnectionFactory,
}
],
}).compile();
service = module.get<ServiceName>(ServiceName);
mockRepository = module.get(getRepositoryToken(User));
mockConnection = module.get<Connection>(Connection);
});
it('should create a new user and return it using Repository', async () => {
// some test that passes using mockRepository
});
it('should create a new user and return it using QueryBuilder (with mocked Connection)', async () => {
expect(await service.createUserQueryBuilder(user)).toEqual(user);
expect(mockConnection.createQueryBuilder).toBeCalled();
expect(mockConnection.createQueryBuilder()['insert']).toBeCalled();
expect(mockConnection.createQueryBuilder()['into']).toBeCalled();
expect(mockConnection.createQueryBuilder()['values']).toBeCalled();
expect(mockConnection.createQueryBuilder()['execute']).toBeCalled();
})
触发以下错误的是第二个测试it('should create a new user and return it using QueryBuilder (with mocked Connection)':
● service tests › Service Functions › should create a new user and return it using QueryBuilder (with mocked Connection)
ConnectionNotFoundError: Connection "default" was not found.
at new ConnectionNotFoundError (error/ConnectionNotFoundError.ts:8:9)
at ConnectionManager.Object.<anonymous>.ConnectionManager.get (connection/ConnectionManager.ts:40:19)
at Object.getConnection (index.ts:252:35)
at ServiceName.createUserQueryBuilder (somefile:19:11)
at Object.it (somefile:134:34)
【问题讨论】:
标签: typescript unit-testing mocking nestjs typeorm