Angular 18 + Jest 29单元测试中router.navigate被误判为调用两次的问题求助
我最近在给Angular 18组件的一个方法写单元测试时遇到了个头疼的问题:组件代码里明明只在HTTP请求成功后调用了一次router.navigate,但测试却提示这个方法被调用了两次,导致断言失败。
先给大家看组件里的目标方法(已经精简了无关代码):
requestInformation_click() { this.showCommentError = !this.comment; // 转成布尔值 if (this.comment) { this.accountsService.requestMoreInformation(this.requestId, this.comment).subscribe( response => { this.router.navigate( [`/list-account-requests/${this.requestId}`], { state: { feedback: '\'Additional info needed\' request sent' } } ); }, ); } }
接下来是我的测试配置和对应测试用例:
// 模拟依赖对象 mockRouter = { navigate: jest.fn() }; mockAccountsService = { requestMoreInformation: jest.fn(() => of()), } await TestBed.configureTestingModule({ // 其他配置项 providers:[ { provide: AccountsService, useValue: mockAccountsService }, { provide: Router, useValue: mockRouter }, ], }) .compileComponents(); it('should route to `list-account-requests/abc123` when requestMoreInformation is successful', () => { component.comment = 'this is a call'; route.snapshot.params.requestId = 'abc123'; const detailsSpy = jest.spyOn(mockAccountsService, 'requestMoreInformation').mockReturnValue(of({ success: true, })); component.requestInformation_click(); expect(mockRouter.navigate).toHaveBeenCalledWith(['/list-account-requests/abc123']); });
VS Code里抛出的测试错误信息如下:
NewAccountRequestDetailsComponent > should route to
list-account-requests/abc123when requestMoreInformation is successfulError: expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: ["/list-account-requests/abc123"]
Received 1 Array [
- "/list-account-requests/abc123",
- "/list-account-requests",
], 2 Array [
- "/list-account-requests/abc123",
- "/list-account-requests/undefined",
],- {"state": {"feedback": "'Additional info needed' request sent"}},
Number of calls: 2
我已经尝试了几种排查方法,都没能解决问题:
- 把断言改成包含
state参数的完整调用,结果还是提示调用了两次; - 在
afterEach钩子中调用jest.clearAllMocks(),没有任何效果; - 怀疑是其他测试用例的影响,把所有涉及router测试的用例都注释掉,重新运行还是一样的错误;
- 我甚至临时加了
expect(mockRouter.navigate).toHaveBeenCalledTimes(2),这个断言居然能通过,说明Jest确实认为它被调用了两次,但我组件里明明只写了一次调用逻辑啊!
另外,我在其他测试用例里测试router.navigate是完全正常的,比如下面这个用例就能顺利通过:
it('should route to `list-account-requests` when requestId is null or undefined', () => { route.snapshot.params.requestId = undefined; component.ngOnInit(); expect(mockRouter.navigate).toHaveBeenCalledWith(['/list-account-requests']); expect(mockRouter.navigate).toHaveBeenCalledTimes(1); });
有没有大佬能帮我分析下,到底为什么这个测试会认为router.navigate被调用了两次呢?
内容来源于stack exchange
相关产品推荐
相关产品推荐

