【发布时间】:2021-08-04 07:04:36
【问题描述】:
我目前正在对我的 NestJS 服务进行单元测试。我的实体称为“用户”,我建立了一个基本服务,允许我与 MS SQL 服务器交互,并在我的控制器中建立 GET 和 POST 端点。
我试图模拟的服务方法之一是deleteV2 函数,您可以在下面找到它:
// service file
import { Injectable } from '@nestjs/common';
import { InjectConnection, InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { Connection, createConnection, EntityManager, getConnection, getManager, getRepository, Repository } from "typeorm";
import {User} from '../entities/user.entity';
@Injectable()
export class ServiceName {
constructor(@InjectRepository(User) private usersRepository: Repository<User>,
@InjectConnection() private connection: Connection,
@InjectEntityManager() private manager: EntityManager
) {}
async delete(id: number): Promise<any> {
return await this.manager.delete(User, id);
}
async deleteV2(id: number): Promise<any> {
return await getManager().delete(User, id);
}
请注意,我导入EntityManager 并在我的服务中注入(使用@InjectEntityManager())manager: EntityManager 的原因很简单,因为我想要更多练习使用不同的方法(我是一名新实习生与 NestJS 一起工作)。事实上,我在使用注入的manager 的地方定义了delete 方法,然后在我使用导入的getManager 的地方定义了deleteV2 方法,这也是以不同方式练习单元测试的纯粹原因。而我注入Repository、Connection、EntityManager,也是出于同样的原因。
在我的 spec.ts 服务单元测试文件中,我有:
// unit testing file for the service
type MockType<T> = {
[P in keyof T]?: jest.Mock<{}>;
};
describe('service tests', () => {
const mockManagerFactory = jest.fn(() => ({
delete: jest.fn().mockReturnValue(undefined),
}))
let service: ServiceName;
// mock repository and mock connection also defined similarly to mockManager
let mockManager: MockType<EntityManager>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ServiceName,
// tokens for Repository and Connection are also provided along with their respective Factories
{
provide: getEntityManagerToken(),
useFactory: mockManagerFactory,
},
],
}).compile();
service = module.get<ServiceName>(ServiceName);
// mockRepository and mockConnection also defined but not shown
mockManager = module.get(getEntityManagerToken());
});
})
在同一个 spec.ts 文件中,我定义了多个测试。引起问题的是下面涉及deleteV2的问题:
// same unit testing file for the service
// first test
it('first test', async () => {
expect(await service.delete(1000)).toEqual(undefined);
expect(mockManager.delete).toBeCalled();
});
// second test
it('second test', async () => {
expect(await service.deleteV2(1000)).toEqual(undefined);
expect(mockManager.delete).toBeCalled();
})
虽然第一个测试运行没有问题(第一个测试与服务文件中的delete关联),但第二个测试(与服务文件中的deleteV2关联)没有通过并导致以下错误:
● service tests › Service Functions › second test
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.getManager (index.ts:260:35)
任何想法如何处理这个错误?似乎提供getEntityManagerToken() 与注入的manager 一起使用,但不适用于导入的getManager,因为deleteV2 使用getManager 而delete(通过测试)使用导入的manager
【问题讨论】:
标签: typescript nestjs