如何在Jest中正确模拟对象内部函数以测试changeFuncInObj?
问题
现有函数 changeFuncInObj,功能是修改传入对象的 anObjFunction 属性,使其返回外部函数 externalFunction 调用结果与参数 someBool 的逻辑与:
const changeFuncInObj = (myObj, someBool) => { myObj.anObjFunction = (event) => { return externalFunction(event.data) && someBool } }
当前Jest测试写法错误,无法触发第3行逻辑,测试返回undefined(预期应根据externalFunction和someBool返回true或false),错误测试代码如下:
test('test function inside object', () => { const myObj = { anObjFunction: jest.fn().mockImplementation(() => { return { externalFunction: jest .fn() .mockReturnValueOnce(true), } }), } let result = changeFuncInObj(myObj, true) expect(result).toEqual(undefined) // should be true or false based on `externalFunction` and `someBool` })
询问是否存在正确模拟对象内部函数、布尔变量及内部函数返回值的方法。
解决方法
错误根源
- 测试中错误地将
myObj.anObjFunction模拟为返回包含externalFunction的对象,但实际changeFuncInObj会直接覆盖myObj.anObjFunction,且原函数中的externalFunction是外部依赖,并非anObjFunction的返回值成员。 - 错误地直接取
changeFuncInObj的返回值,但该函数没有返回值(仅修改传入对象的属性),需调用修改后的myObj.anObjFunction才能得到预期结果。
正确测试步骤
- 模拟外部依赖:如果
externalFunction是模块导出的函数,用jest.mock或jest.spyOn模拟;如果是全局函数,直接用jest.fn()替换。 - 创建基础测试对象:无需提前模拟
anObjFunction,因为changeFuncInObj会覆盖它。 - 执行目标函数:调用
changeFuncInObj传入测试对象和指定的someBool值。 - 调用修改后的函数:调用
myObj.anObjFunction并传入包含data的event参数。 - 断言结果与调用情况:验证返回值是否符合预期,同时可断言
externalFunction是否被正确调用。
完整测试代码示例
// 先模拟外部依赖externalFunction const externalFunction = jest.fn(); test('changeFuncInObj returns true when externalFunction and someBool are both true', () => { const myObj = {}; externalFunction.mockReturnValue(true); changeFuncInObj(myObj, true); const result = myObj.anObjFunction({ data: 'test-data' }); expect(result).toBe(true); expect(externalFunction).toHaveBeenCalledWith('test-data'); }); test('changeFuncInObj returns false when externalFunction is true but someBool is false', () => { const myObj = {}; externalFunction.mockReturnValue(true); changeFuncInObj(myObj, false); const result = myObj.anObjFunction({ data: 'test-data' }); expect(result).toBe(false); }); test('changeFuncInObj returns false when externalFunction is false', () => { const myObj = {}; externalFunction.mockReturnValue(false); changeFuncInObj(myObj, true); const result = myObj.anObjFunction({ data: 'test-data' }); expect(result).toBe(false); });
内容的提问来源于stack exchange,提问作者Ayman Patel
相关产品推荐
相关产品推荐

