You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular单元测试如何Mock嵌套方法?为何出现未定义错误?

问题原因及解决方案

核心错误原因

你遇到的Cannot read properties of undefined (reading 'search')是因为组件构造函数执行时机早于mock返回值的设置:
当调用TestBed.createComponent(LoginPageComponent)时,组件实例会被创建,构造函数立即执行this.angularLocation = locationHelperService.getLocation()。但此时你还没给mockLocationService.getLocation设置返回值,jasmine spy默认返回undefined,导致this.angularLocation变成undefined,后续调用redirectToDashboard时自然找不到search()方法。

另外还有个小问题:你mock的search()方法返回{ path: { ref: '/other-page' } },但组件里判断的是path.ref,这会导致path.ref始终为undefined,永远走else分支跳转到/dashboard,和你预期的测试逻辑不符。

修正后的测试代码

const mockLocationService = jasmine.createSpyObj('LocationHelperService', ['getLocation']);
// 先创建mock的location对象,包含需要的方法
const mockAngularLocation = {
  search: jasmine.createSpy().and.returnValue({ ref: '/other-page' }),
  url: jasmine.createSpy(),
  path: jasmine.createSpy()
};

beforeEach(() => {
  TestBed.configureTestingModule({
    // 其他配置
    providers: [
      { provide: LocationHelperService, useValue: mockLocationService },
    ],
  }).compileComponents();

  // 关键:先设置getLocation的返回值,再创建组件
  mockLocationService.getLocation.and.returnValue(mockAngularLocation);

  fixture = TestBed.createComponent(LoginPageComponent);
  component = fixture.componentInstance;
});

it('should redirect to the ref path when ref exists', waitForAsync(() => {
  fixture.detectChanges();
  
  const loginButton = fixture.debugElement.nativeElement.querySelector('#login-button');
  loginButton.click();

  fixture.detectChanges();

  fixture.whenStable().then(() => {
    // 验证search方法被调用
    expect(mockAngularLocation.search).toHaveBeenCalled();
    // 验证跳转到了指定的ref路径
    expect(mockAngularLocation.url).toHaveBeenCalledWith('/other-page');
    // 如果测试无ref的情况,只需修改search的返回值为{},然后断言path被调用
  });
}));

关键修改点

  1. 调整mock设置顺序:在createComponent之前就给mockLocationService.getLocation设置返回值,确保组件构造函数执行时能拿到正确的mock对象。
  2. 修正返回结构:让search()直接返回{ ref: '/other-page' },匹配组件里path.ref的判断逻辑。
  3. 给mock方法添加spy:对url和path方法也创建spy,方便后续验证跳转行为是否符合预期。

内容的提问来源于stack exchange,提问作者zen zen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:00:17