Angular 测试:返回可观察对象的方法已成功测试,但测试覆盖率仍将其标记为未覆盖语句

Angular testing: Method returning an observable is successfully tested, but test coverage still marks it as noncovered statement

我想测试这个方法:

public getAll(): Observable<Array<Todo>> {
    return this.$http.get<Array<Todo>>('http://5def6a2502b2d90014e1b38a.mockapi.io/api/v1/todos/');
}

我已经为这个方法写了一个测试:

it('should return array of todos', (done: DoneFn) => {
    const mockedValue = [new Todo('Test')];
    spyOn(service, 'getAll').and.returnValue(of(mockedValue));
    service.getAll().subscribe((value) => {
        expect(value).toBe(mockedValue);
        done();
    });
});

当我 运行 ng test 时,此测试被标记为成功,但代码覆盖率仍将其标记为未覆盖测试:

为什么?我该如何覆盖它?

您正在嘲笑您尝试测试的方法。这就是为什么报道说这没有经过测试。

对于您的测试用例,您只是在验证您的模拟是否有效,而不是该函数执行您期望的操作。

你不应该模拟 getAll 而应该模拟 http 客户端。

HttpClientTestingModule 正是针对这些情况。

您需要在 TestBed 中包含此模块

beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [YourServiceUnderTest],
      imports: [HttpClientTestingModule]
    });
});

使用此设置,您可以编写如下测试:

  it('getAll', () => {
    const mockResponse: Todo[] = [new Todo(1)];
    const service = TestBed.get(YourServiceUnderTest);
    const httpTestingController = TestBed.get(HttpTestingController);

    service.getAll()
      .subscribe(data => {
        expect(data).toEqual(mockResponse);
      });

    const req = httpTestingController.expectOne('YOUR-URI-GOES-HERE');

    expect(req.request.method).toEqual('GET');

    req.flush(mockCourse);
  });

也许看看那些文章:

Testing Http Requests

Testing with HttpClient