如何使用Jest模拟TypeORM的merge函数?NestJS用户更新测试属性不生效
问题原因
- 你对TypeORM Repository的
merge方法的Mock实现和原生行为不符
TypeORM原生merge方法的逻辑是直接修改传入的第一个实体对象的属性,不会生成新的对象实例,而你现在的Mock实现是返回了一个全新的对象,业务代码中并没有接收merge的返回值,所以原user变量的属性根本没有被修改,自然更新失败。 - 未Mock
save方法(非核心报错原因,但单元测试场景下建议补充)
你的单元测试中没有对save方法做Mock,测试运行时可能会调用真实的数据库操作,不符合单元测试隔离依赖的要求。
修复方案
修改users.service.spec.ts中的测试代码,调整merge的Mock实现,补充save的Mock即可:
it('should update user with new information', async () => { const userPropertiesToUpdate = { firstName: 'peter', }; const updateUserDto = plainToClass(UpdateUserDto, userPropertiesToUpdate); // 提前声明模拟的用户实例,方便后续mock使用 const mockUser = plainToClass(User, UserMockFactory.build()); jest .spyOn(repository, 'findOne') .mockResolvedValue(mockUser); jest .spyOn(repository, 'merge') .mockImplementation((user, updateDto) => { // 直接修改原对象,和原生merge行为一致 Object.assign(user, updateDto); return user; }); // 补充save方法的mock jest.spyOn(repository, 'save').mockResolvedValue(mockUser); const result = await service.update( '3b06c85a-698b-4410-bd31-b8b2990eec3a', updateUserDto, ); // 可以直接加断言验证结果,不需要打印 expect(result.firstName).toBe('peter'); });
额外建议
如果后续仍然出现字段不更新的问题,可以排查以下两点:
- 确认
UpdateUserDto中对应要更新的字段没有加@IsReadOnly或者其他校验规则阻止赋值 - 确认
User实体类的对应属性没有设置update: false的TypeORM字段注解
内容的提问来源于stack exchange,提问作者Laycoonz
相关产品推荐
相关产品推荐

