如何为Angular组件ngOnInit中的subscribe编写单元测试?
Angular ngOnInit 单元测试覆盖next/error分支方案
问题描述
我有如下的ngOnInit函数:
ngOnInit() { const result = this.authService.authorizeUser().subscribe({ next: (res) => (this.isAuthorized = res.authorized), error: (err) => new alert('You do not have the required AD group'), }); return result; }
我需要编写单元测试覆盖其中的next和error分支,但尝试多种方案都无法覆盖目标代码分支,刚接触Angular测试,以下是我试过的测试代码(测试通过但未覆盖目标分支):
it('should call auth and return values', async () => { let mockItem: AuthResponse = {employeeId: 'test', authorized: true}; let spy = jest.spyOn(component, "ngOnInit"); component.ngOnInit(); expect(spy).toHaveBeenCalled(); expect(mockItem).toBeDefined(); }); it('should set isAuthorized to false', () => { const mockResponse = {employeeId: 'test', authorized: true }; authServiceMock.authorizeUser.mockReturnValue(of(mockResponse)); component.ngOnInit(); expect(component.isAuthorized).toBe(false); });
正确测试方案
要覆盖两个分支,核心是模拟authService.authorizeUser()的返回值,分别返回成功的Observable和抛出错误的Observable,再验证对应逻辑是否执行。
1. 覆盖next分支(授权结果返回场景)
// 测试授权成功时isAuthorized设为true it('should set isAuthorized to true when authorization succeeds', () => { const mockSuccessResponse: AuthResponse = { employeeId: 'test', authorized: true }; // 模拟authService返回成功的Observable authServiceMock.authorizeUser.mockReturnValue(of(mockSuccessResponse)); component.ngOnInit(); expect(component.isAuthorized).toBe(true); expect(authServiceMock.authorizeUser).toHaveBeenCalled(); }); // 测试授权失败时isAuthorized设为false it('should set isAuthorized to false when authorization returns unauthorized', () => { const mockFailResponse: AuthResponse = { employeeId: 'test', authorized: false }; authServiceMock.authorizeUser.mockReturnValue(of(mockFailResponse)); component.ngOnInit(); expect(component.isAuthorized).toBe(false); });
2. 覆盖error分支(请求出错场景)
it('should show alert when authorization fails with error', () => { // 模拟alert函数,避免真实弹窗干扰测试 window.alert = jest.fn(); // 模拟authService抛出错误 const mockError = new Error('Authorization failed'); authServiceMock.authorizeUser.mockReturnValue(throwError(() => mockError)); component.ngOnInit(); expect(window.alert).toHaveBeenCalledWith('You do not have the required AD group'); expect(authServiceMock.authorizeUser).toHaveBeenCalled(); });
原测试代码的问题
- 第一个测试仅监听了
ngOnInit是否被调用,未验证授权逻辑的执行,完全触达不了next/error分支 - 第二个测试中模拟的响应是
authorized: true,却断言isAuthorized为false,逻辑矛盾,测试通过但未命中正确业务逻辑
内容的提问来源于stack exchange,提问作者AndriusM
相关产品推荐
相关产品推荐

