单元测试中如何Mock属性链式调用的getCurrentAccountInfo函数
解决Jasmine中Mock链式属性调用的问题
你的核心问题是Mock的层级和业务代码的调用路径不匹配:业务代码里调用的是window.Portal.Account.getCurrentAccountInfo(),但你直接在window对象上挂载了getCurrentAccountInfo方法,完全没构建Portal和Account这两层嵌套结构,导致代码执行时找不到目标方法,Mock自然失效。
以下是两种可行的解决方式:
方式一:分步构建嵌套Spy对象
逐层创建每个层级的Spy对象,确保调用路径完全匹配:
// 1. 先Mock最内层的Account,包含目标方法 const accountSpy = jasmine.createSpyObj('Account', ['getCurrentAccountInfo']); accountSpy.getCurrentAccountInfo.and.returnValue({ name: 'My Account' }); // 2. 构建Portal层,挂载Account对象 const portalSpy = { Account: accountSpy }; // 3. 构建最终的window对象,挂载Portal层 const mockWindow = { Portal: portalSpy }; // 执行测试逻辑 component.setAccountInfo(mockWindow); expect(component.accountInfo).toEqual({ name: 'My Account' }); // 可选:验证目标方法是否被正确调用 expect(accountSpy.getCurrentAccountInfo).toHaveBeenCalled();
方式二:使用Jasmine createSpyObj的嵌套属性定义
如果你的Jasmine版本支持,可通过createSpyObj的第三个参数直接定义嵌套属性,写法更简洁:
// 一次性构建完整的嵌套结构 const mockWindow = jasmine.createSpyObj('window', {}, { Portal: jasmine.createSpyObj('Portal', {}, { Account: jasmine.createSpyObj('Account', ['getCurrentAccountInfo']) }) }); // 设置目标方法的返回值 mockWindow.Portal.Account.getCurrentAccountInfo.and.returnValue({ name: 'My Account' }); // 执行测试 component.setAccountInfo(mockWindow); expect(component.accountInfo).toEqual({ name: 'My Account' });
说明:
createSpyObj的第二个参数用于定义方法名数组,第三个参数用于定义非方法的属性(这里用来构建嵌套层级),确保window.Portal.Account的调用路径完全对应业务代码。
内容的提问来源于stack exchange,提问作者inquisitivemongoose
相关产品推荐
相关产品推荐

