如何用jest.spyOn正确模拟类中的Promise异步方法?
问题解决方法
你的测试用例存在两个核心问题,导致function2的模拟未生效,以下是具体修正方案:
1. 改用mockResolvedValue模拟异步方法返回值
function2是异步函数,返回的是Promise对象,你之前用mockReturnValue返回普通对象,虽然await可以兼容非Promise值,但Jest的异步执行时序会导致模拟失效(Debug模式下执行速度慢,时序问题被掩盖)。必须用mockResolvedValue返回一个已决议的Promise,确保await this.function2()能正确获取模拟值。
2. 针对类原型方法进行Spy
你的function2是类的原型方法,直接Spy已导出的实例方法,可能因实例创建时机早于Spy操作,导致原方法仍被调用。Spy类的原型方法能确保所有实例(包括已创建的导出实例)的该方法都被模拟。
3. 修正断言逻辑
当function2返回status:400时,function1的逻辑会返回false,你原测试的expect(response).toEqual(true)是错误的,需要修正为断言false。
修改后的测试用例
const myClassInstance = require('./myClass'); // 导入导出的实例 test("test 1", async () => { // 针对类原型的function2方法创建Spy,并模拟返回值 jest.spyOn(myClassInstance.constructor.prototype, 'function2') .mockResolvedValue({ status: 400 }); const response = await myClassInstance.function1(); expect(response).toEqual(false); // 修正后的断言 });
额外优化:避免模块缓存影响
如果你的测试文件存在多次导入实例的情况,可以在测试前重置模块缓存,确保每次测试都是全新的实例:
beforeEach(() => { jest.resetModules(); }); test("test 1", async () => { const myClassInstance = require('./myClass'); // 在测试内导入,确保每次都是新实例 jest.spyOn(myClassInstance.constructor.prototype, 'function2') .mockResolvedValue({ status: 400 }); const response = await myClassInstance.function1(); expect(response).toEqual(false); });
内容的提问来源于stack exchange,提问作者John Glabb
相关产品推荐
相关产品推荐

