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

Angular 7测试用例:如何覆盖localStorage与subscribe及错误函数代码

Fixing Code Coverage for localStorage and subscribe Callbacks in Angular 7 Tests

Got it, let’s tackle those uncovered lines and callback functions in your Angular 7 test suite. I’ll walk you through how to mock dependencies, trigger the right code paths, and verify everything works as expected.

1. Mock localStorage and Verify Its Usage

Angular’s test environment doesn’t include a real localStorage instance, so we need to mock it and spy on its methods to ensure localStorage.setItem gets covered:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { YourLoginComponent } from './your-login.component';
import { ValService } from './val.service';
import { of } from 'rxjs';

describe('YourLoginComponent', () => {
  let component: YourLoginComponent;
  let valService: ValService;
  let localStorageSetItemSpy: jasmine.Spy;

  beforeEach(async () => {
    // Mock localStorage
    const mockLocalStorage = {
      setItem: jasmine.createSpy('setItem'),
      getItem: jasmine.createSpy('getItem'),
      removeItem: jasmine.createSpy('removeItem'),
      clear: jasmine.createSpy('clear')
    };
    Object.defineProperty(window, 'localStorage', { value: mockLocalStorage });
    localStorageSetItemSpy = window.localStorage.setItem;

    await TestBed.configureTestingModule({
      declarations: [YourLoginComponent],
      providers: [
        { 
          provide: ValService, 
          useValue: { checkVal: jasmine.createSpy('checkVal').and.returnValue(of({})) } 
        }
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    const fixture = TestBed.createComponent(YourLoginComponent);
    component = fixture.componentInstance;
    valService = TestBed.inject(ValService);
    fixture.detectChanges();
  });

  // Test for localStorage.setItem coverage
  it('should save email to localStorage on successful login', () => {
    const testEmail = 'user@example.com';
    const testPassword = 'test123';

    // Trigger your login method (adjust the method name to match your code)
    component.onLogin(testEmail, testPassword);

    // Verify localStorage.setItem was called with the right parameters
    expect(localStorageSetItemSpy).toHaveBeenCalledWith('email', testEmail);
  });
});

2. Cover the subscribe Success Callback

To hit the success block of your subscribe, make sure valService.checkVal returns a successful Observable. Then verify any logic inside that callback:

it('should handle successful validation correctly', () => {
  const mockSuccessResponse = { isValid: true };
  // Override the spy to return a success Observable
  (valService.checkVal as jasmine.Spy).and.returnValue(of(mockSuccessResponse));

  component.onLogin('user@example.com', 'test123');

  // Add assertions for any logic in your success callback
  // Example: If you set an isLoggedIn flag, check it here
  expect(component.isLoggedIn).toBeTrue();
});

3. Cover the subscribe Error Callback (Your Missing isLoginError Logic)

This is the part where this.isLoginError = true wasn’t being covered. We’ll make checkVal return an error Observable to trigger this path:

import { throwError } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';

// ... inside your describe block

it('should set isLoginError to true when validation fails', () => {
  // Create a mock HttpErrorResponse to simulate the error
  const mockError = new HttpErrorResponse({
    status: 401,
    statusText: 'Unauthorized',
    error: 'Invalid credentials'
  });

  // Make checkVal return an error Observable
  (valService.checkVal as jasmine.Spy).and.returnValue(throwError(() => mockError));

  component.onLogin('wrong@example.com', 'wrongpass');

  // Verify the error callback logic ran
  expect(component.isLoginError).toBeTrue();
});

Quick Tips to Ensure Full Coverage

  • If your success callback has additional logic (like routing or setting other flags), add assertions for those too
  • Double-check that your login method is actually being called in each test (use expect(valService.checkVal).toHaveBeenCalledWith(...) to confirm)
  • If you’re using Jest instead of Jasmine, the syntax for spies and observables is slightly different, but the core approach (mock dependencies, control Observable output) stays the same

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:18:59