[英]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.