![](/img/trans.png)
[英]NestJS Unit Testing of the Service: Mocking getManager resulting in 'Connection "default" was not found' error
[英]Connection "default" was not found with NestJS Unit Testing of Service
我目前正在对我的 NestJS 服务进行单元测试。 我的实体称为“用户”,我建立了一个基本服务,允许我与 MS SQL 服务器交互,并在我的 Controller 中建立 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)
最简单的解决方案是更改您的createUserQueryBuilder
方法,如下所示:
async createUserQueryBuilder(user: User): Promise<User> {
await this.usersRepository
.createQueryBuilder()
.insert()
.into(User)
.values([
user,
])
.execute();
return user;
}
然后您可以更新存储库模拟repositoryMockFactory
:
const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({
create: jest.fn(),
save: jest.fn(),
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),
}));
根据您的要求,您也可以这样做。
更新您的spec.ts
文件,
import * as typeorm from 'typeorm';
const getConnectionSpy = jest.spyOn(typeorm, 'getConnection');
getConnectionSpy.mockImplementation(() => ({
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),
}));
请注意,您必须相应地更新您的其他typeorm
导入。 例如: typeorm.Connection
这只是为了让您了解如何做到这一点。 由于我没有对此进行测试,因此可能存在语法错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.