Jest测试中jest.fn()的toHaveBeenCalled()断言不生效问题求助
问题排查与解决方案
核心问题分析
- 实例不匹配:测试中通过
module.get(MockRepository)获取的实例,和Nest DI容器注入给业务组件的实例并非同一个。你在providers里配置的是用MockRepository实现DataRepository,容器是以DataRepository作为标识存储实例的,直接获取MockRepository会生成新实例,导致spy监听的对象不对。 - 方法名错误:
MockRepository里定义的方法是dataAccess,但测试中spy的是checkData,方法名不匹配自然捕获不到调用。 - 冗余的await断言:
toHaveBeenCalled这类断言是同步操作,不需要用await包裹。
修正后的测试代码
beforeAll(async () => { module = await Test.createTestingModule({ imports: [AppModule], controllers: [DataController], providers: [ { provide: DataRepository, useClass: MockRepository }, DataService, ] }).compile() app = module.createNestApplication() await app.init() // 拿到DI容器中实际被业务组件使用的实例 repository = module.get<DataRepository>(DataRepository) }) it('should test the /addData endpoint', async () => { // 基于正确的实例,对目标方法创建spy const dataAccessSpy = jest.spyOn(repository, 'dataAccess') const createDataSpy = jest.spyOn(repository, 'createData') const response = await request(app.getHttpServer()) .post('/api/addData') .send(mockRequestBody) // 同步断言,无需await expect(dataAccessSpy).toHaveBeenCalled() expect(createDataSpy).not.toBeCalled() expect(response.body).toEqual({ allowed: true }) })
额外验证建议
- 在
MockRepository的dataAccess方法中添加console.log('dataAccess被调用'),确认接口请求时该方法确实被触发。 - 检查
DataService是否正确注入了DataRepository,且处理/addData请求时确实调用了dataAccess方法。
内容的提问来源于stack exchange,提问作者arj
相关产品推荐
相关产品推荐

