如何在Jest中Mock同一类中返回Promise的方法?
解决方案
别担心,第一次用Jest处理类方法的Promise Mock确实容易摸不着头绪,我来给你两种简单可行的方案,都是专门针对你这种场景的:
方法一:直接替换实例的bar方法
你可以直接给Blah实例的bar方法重新赋值,让它返回一个已经resolve指定值的Promise:
import Blah from './blah' test('foo() - bar() resolves "what up"', async () => { const blah = new Blah() // 直接mock bar方法,让它resolve "what up" blah.bar = jest.fn().mockResolvedValue('what up') // 执行foo方法,用await等待异步逻辑完成 await blah.foo() // 这里写你的断言,比如如果foo里把result存到了实例属性里: // expect(blah.someProperty).toBe('what up') // 还可以断言bar方法被调用了 expect(blah.bar).toHaveBeenCalled() })
方法二:用jest.spyOn(更推荐)
jest.spyOn可以帮你更优雅地mock方法,还能随时恢复原始方法,适合需要多次测试不同场景的情况:
import Blah from './blah' test('foo() - bar() resolves "what up"', async () => { const blah = new Blah() // 监听blah实例的bar方法,并用mockResolvedValue指定resolve值 const barSpy = jest.spyOn(blah, 'bar').mockResolvedValue('what up') await blah.foo() // 你的断言逻辑 // expect(...) // 断言bar被调用了一次 expect(barSpy).toHaveBeenCalledTimes(1) // 测试结束后恢复原始的bar方法(可选,如果你后面的测试不需要mock的话) barSpy.mockRestore() })
关键注意点:处理异步逻辑
因为foo里用到了then异步回调,测试必须等待异步操作完成,否则Jest会在逻辑执行完前就结束测试。上面的例子用了async/await,你也可以用done回调或者返回Promise的方式:
// 用done回调的写法 test('foo() - bar() resolves "what up"', (done) => { const blah = new Blah() blah.bar = jest.fn().mockResolvedValue('what up') blah.foo() // 等待bar的Promise完成后执行断言 blah.bar().then(() => { expect(blah.bar).toHaveBeenCalled() done() }) })
如果你的foo方法本身返回了Promise(比如把this.bar().then(...) return出去),那测试里直接返回blah.foo()就可以让Jest自动等待它完成。
内容的提问来源于stack exchange,提问作者Juicy
相关产品推荐
相关产品推荐

