【发布时间】:2021-09-20 15:35:56
【问题描述】:
我想用模拟服务为我的 http 控制器编写单元测试。 主要思想是模拟服务并为其提供一些模拟实现。
这是我的设置(我将跳过一些导入语句并且在我们的上下文装饰器中无用以减少代码行数量):
create-user.http.controller.ts:
export class CreateUserHttpController {
constructor(
@Inject(createUserSymbol)
private readonly createUser: CreateUserService,
) {}
@Post(appRoutes.users.root)
async create(@Body() body: CreateUserRequest): Promise<IdResponse> {
const command = new CreateUserCommand({
email: body.email,
name: body.name,
password: body.password,
role: 'user',
});
const id = await this.createUser.createUser(command);
return new IdResponse(id.value);
}
}
create-user.http.controller.spec.ts:
import { Test } from '@nestjs/testing';
import { ID } from 'src/core/value-objects/id.value-object';
import { createUserSymbol } from '../../user.providers';
import { CreateUserHttpController } from './create-user.http.controller';
import { CreateUserService } from './create-user.service';
jest.mock('./create-user.service', () => {
return {
CreateUserService: jest.fn().mockImplementation(() => {
return {
createUser: () => {
console.log('ts');
},
};
}),
};
});
describe('CreateUserHttpController', () => {
let createUserHttpController: CreateUserHttpController;
let createUserService: CreateUserService;
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
controllers: [CreateUserHttpController],
providers: [
{
provide: createUserSymbol,
useValue: CreateUserService,
},
],
}).compile();
createUserHttpController = await moduleRef.resolve(
CreateUserHttpController,
);
createUserService = await moduleRef.resolve(createUserSymbol);
});
describe('create', () => {
it('should call once createUser method in service', async () => {
const expectedResult = new ID('test');
jest
.spyOn(createUserService, 'createUser')
.mockResolvedValue(expectedResult);
const result = await createUserHttpController.create({
email: 'test@mail.ru',
name: 'test',
password: 'test',
});
expect(createUserService).toHaveBeenCalledTimes(1);
});
});
});
通过这种设置,我遇到了这样的问题: (无法窥探属性,因为它不是函数;改为未定义)
我尝试通过 console.log 模拟服务实例来检查是否存在“createUser”属性。而且它似乎不存在。
我已经深入检查了 jest 文档,尤其是这里 - jest doc for mocking non-default class exports。我花了大约 6 个小时尝试了所有可用的选项,但结果还是一样。
我还在这里查看了指南 - medium guide。这个幸运的家伙似乎有相同的设置,没有任何问题。
所以,从我的角度来看,jest.mock 函数由于某种原因没有使用createUser 方法初始化模拟服务。
任何帮助表示赞赏!提前致谢。
【问题讨论】:
-
你有什么理由使用
moduleRef.resolve而不是moduleRef.get? -
@JayMcDoniel resolve 看起来更简单 :) 我相信在这种情况下获得一个唯一的提供者实例很好。顺便说一句,我已经尝试过
.get并且没有任何变化。 -
resolve通常适用于TRANSIENT和REQUEST范围内的提供程序,虽然我相信它可以与SINGLETON一起使用,但通常最好使用正确的 API为它。 -
@JayMcDoniel 同意,我会深入探讨这个话题,谢谢
标签: typescript unit-testing jestjs mocking nestjs