Jest单元测试报Received promise resolved instead of rejected
问题根因
测试报错由三个核心问题导致:
- 误用RxJS操作符:你调用的
throwError是RxJS库的方法,返回值是携带_subscribe方法的Observable实例,既不是原生错误对象,也不会触发Promise reject。你把这个实例传入mockResolvedValueOnce,相当于让findOne返回了一个成功状态的Promise,resolve值就是这个Observable对象。业务代码判断!userPreferences时,Observable是truthy值,不会进入抛错分支,最终getPreferences返回的是resolved状态的Promise,和你断言的rejected状态不符,控制台打印的resolve值也正好对应Observable的结构。 - Mock逻辑与业务不匹配:你的业务代码中,
NotFoundException('no results')是findOne查询成功但返回空结果时主动抛出的,并非findOne方法本身抛出的错误,当前mock思路完全不符合代码实际运行路径。 - 细节错误:你实例化
NotFoundException时没有传入'no results'参数,就算mock逻辑正确,断言匹配错误消息时也会失败。
正确修复方案
优先按照真实业务场景编写用例,模拟findOne查询无结果返回null的情况,让业务代码自己触发抛错逻辑,这样才能真正验证服务层的判断分支:
it('should throw an error if no userPreferences found', async () => { // Mock findOne查询不到数据,返回null jest .spyOn(model, 'findOne') .mockResolvedValueOnce(null); // 断言抛出预期的错误 await expect(service.getPreferences('123123')).rejects.toThrow( new NotFoundException('no results') ); });
如果你需要单独测试数据库请求异常的场景(即findOne本身返回rejected Promise),不要使用RxJS的throwError,直接用Jest提供的mockRejectedValueOnce模拟Promise拒绝即可:
it('should throw error when database request failed', async () => { const dbError = new Error('database connection error'); jest .spyOn(model, 'findOne') .mockRejectedValueOnce(dbError); await expect(service.getPreferences('123123')).rejects.toThrow(dbError); });
内容的提问来源于stack exchange,提问作者DavSev
相关产品推荐
相关产品推荐

