NestJS单元测试遇Jest匹配器错误:received value must be a promise
解决NestJS单元测试中的
Matcher error: received value must be a promise错误 我在给NestJS应用编写单元测试时,碰到了一个无法解决的错误:Matcher error: received value must be a promise,但明明已经对Promise做了处理。
相关代码
Service层的update方法
async update(uname: string, updateUserDto: UpdateUserDTO): Promise<Users> { const updateUser = await prisma.users.findUnique({ where: { username: uname, }, }); if (!updateUser || updateUser.username !== uname) { throw new NotFoundException('User not found'); } await prisma.tasks.updateMany({ where: { userId: uname, }, data: { userId: uname, }, }); return prisma.users.update({ where: { username: uname, }, data: { ...updateUserDto, }, }); }
Controller层的update方法
@Patch(':uname') update(@Param('uname') uname: string, @Body() updateUserDto: UpdateUserDTO) { return this.usersService.update(uname, updateUserDto); }
测试代码及Mock配置
测试用例
describe('Update a user', () => { it('should update the username of a user', async () => { const updatedUser: UpdateUserDTO = { name: 'Hulk', }; await expect( controller.update('wolverine', updatedUser) ).resolves.toEqual({ username: 'wolverine', ...updatedUser, }); }); });
Service的Mock实现
update: jest .fn() .mockImplementation((username: string, user: UpdateUserDTO) => Promise.resolve({ username, ...user }) ),
问题原因及解决办法
这个错误本质是传给expect()的值并非Promise,即便看起来controller的update方法返回了Service层的Promise,也可能因为写法或配置问题导致识别异常。以下是可行的解决步骤:
1. 替换断言写法
放弃.resolves匹配器,直接await方法结果后再断言,这种写法更稳妥,也能避免jest匹配器的潜在问题:
it('should update the username of a user', async () => { const updatedUser: UpdateUserDTO = { name: 'Hulk', }; // 先await获取结果 const response = await controller.update('wolverine', updatedUser); // 直接断言结果 expect(response).toEqual({ username: 'wolverine', ...updatedUser, }); // 额外断言Service方法是否被正确调用 expect(service.update).toHaveBeenCalledWith('wolverine', updatedUser); });
2. 验证Mock的Service注入正确性
确保测试模块中,controller依赖的是你Mock的UsersService实例,而非真实Service:
let controller: UsersController; let service: UsersService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [UsersController], providers: [ { provide: UsersService, useValue: { update: jest.fn().mockImplementation((username, user) => Promise.resolve({ username, ...user }) ), // 其他需要Mock的Service方法 }, }, ], }).compile(); controller = module.get<UsersController>(UsersController); service = module.get<UsersService>(UsersService); });
如果使用真实Service,测试环境中未配置的Prisma会导致数据库连接异常,虽然也会触发Promise reject,但错误提示不会是"received value must be a promise"。
内容的提问来源于stack exchange,提问作者AnonymousGeese
相关产品推荐
相关产品推荐

