Angular2单元测试问题:验证router.navigate调用失败
排查Angular测试中Router Spy未被调用的问题
你遇到的这个测试失败问题,核心原因是mockRouter的初始化时机错误,导致组件实际使用的Router实例并不是你创建的带spy的那个对象。
具体问题分析
看你的beforeEach代码:
beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent], imports: [FormsModule, HttpClientTestingModule], providers: [ { provide: Router, useValue: mockRouter }] // 这里mockRouter还未定义,值为undefined }); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; mockRouter = { navigate: jasmine.createSpy('navigate') }; // 此时才创建带spy的对象,但已错过注入时机 });
当你配置TestBed时,mockRouter还没有被赋值,此时传入的useValue是undefined。之后你才创建了带有navigate spy的对象,但这个对象并没有被注入到组件里——组件拿到的是之前那个undefined的Router实例,所以调用showProfile时,自然不会触发你期望的spy调用。
修复方案
调整代码顺序,先创建带spy的mockRouter,再配置TestBed,这样TestBed才能把正确的mock对象注入到组件中:
beforeEach(() => { // 第一步:先初始化带spy的mockRouter mockRouter = { navigate: jasmine.createSpy('navigate') }; // 第二步:用已初始化的mockRouter配置TestBed TestBed.configureTestingModule({ declarations: [ AppComponent], imports: [FormsModule, HttpClientTestingModule], providers: [ { provide: Router, useValue: mockRouter }] }); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; });
修改之后,组件里的router依赖就是你创建的带有spy的mock对象了,调用showProfile(12345)时,navigate spy会被正确触发,测试就能通过。
额外小提示
如果你的导航逻辑涉及异步操作(比如路由守卫),可以用fakeAsync和tick来确保异步操作完成后再断言,但你的当前场景是同步调用navigate,所以不需要额外处理。
内容的提问来源于stack exchange,提问作者Present practice
相关产品推荐
相关产品推荐

