如何用Jest正确监视object.functionOne().functionTwo()中的functionTwo?
解决Jest无法监视链式调用中
functionTwo的问题 问题根源
每次调用object.functionOne()都会返回一个全新的对象。你在测试里提前调用object.functionOne()拿到的对象,和execute函数中调用object.functionOne()返回的对象不是同一个引用。因此你给前一个对象的functionTwo添加的监视,根本不会被后一个对象的functionTwo调用触发。
修复方案
有两种实用的修复方式:
方式一:复用同一个返回对象
提前定义functionOne要返回的对象,让每次调用都返回同一个引用:
describe('', () => { // 提前定义functionOne的返回对象,确保每次调用返回同一个引用 const functionOneReturnObj = { functionTwo: () => {} }; const object = { functionOne: () => functionOneReturnObj }; const execute = object => object.functionOne().functionTwo(); it('should call functionOne', () => { const functionOneSpy = jest.spyOn(object, 'functionOne'); execute(object); expect(functionOneSpy).toHaveBeenCalled(); }); it('should call functionTwo', () => { const functionTwoSpy = jest.spyOn(functionOneReturnObj, 'functionTwo'); execute(object); expect(functionTwoSpy).toHaveBeenCalled(); }); });
方式二:Mock functionOne的返回值
通过MockfunctionOne,让它返回一个带有监视函数的对象:
describe('', () => { const object = { functionOne: () => ({ functionTwo: () => {} }) }; const execute = object => object.functionOne().functionTwo(); it('should call functionOne', () => { const functionOneSpy = jest.spyOn(object, 'functionOne'); execute(object); expect(functionOneSpy).toHaveBeenCalled(); }); it('should call functionTwo', () => { // 创建一个被Jest监视的functionTwo const mockFunctionTwo = jest.fn(); // Mock functionOne,让它返回包含这个监视函数的对象 jest.spyOn(object, 'functionOne').mockReturnValue({ functionTwo: mockFunctionTwo }); execute(object); expect(mockFunctionTwo).toHaveBeenCalled(); }); });
核心逻辑
两种方案的本质都是确保:测试中监视的functionTwo,和execute调用时实际执行的functionTwo是同一个引用。第一种适合原代码允许复用返回对象的场景,第二种无需修改原对象结构,通过Mock完全控制返回值,灵活性更强。
内容的提问来源于stack exchange,提问作者Yael Badillo
相关产品推荐
相关产品推荐

