如何在没有模拟和间谍的情况下测试 API?

How to test API without mocks and spies?

有包含 2 个方法的服务:

export class CounterService {
  constructor(private http: HttpClient) {}

  getGirls(): Observable<any> {
    return this.http.get<any>('http://localhost:3000/girls');   // return some JSON
  }

  getObservableValue() {
    return of('observable value');
  }
}

我尝试编写单元测试:

describe('CounterService', () => {
  let service: CounterService;

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

  it(
    'test should wait for CounterService.getObservableValue',
    waitForAsync(() => {
      service
        .getObservableValue()
        .subscribe((value) => expect(value).toBe('observable value'));
    })
  );

  it(
    'test should wait for CounterService.getGirls',
    waitForAsync(() => {
      service
        .getGirls()
        .subscribe((value) => expect(value).toBeTruthy());
    })
  );
});

结果测试'test should wait for CounterService.getObservableValue'成功,但测试'test should wait for CounterService.getGirls '不成功。

Jasmine 显示以下消息:

SPEC HAS NO EXPECTATIONS: test should wait for CounterService.getGirls

请帮我测试 getGirls() 没有间谍和任何模拟。有可能吗?

您必须使用 HttpTestingController 发送请求。

describe('CounterService', () => {
  let service: CounterService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [CounterService],
    });
    service = TestBed.inject(CounterService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  afterEach(() => {
    // ensure no outstanding API calls
    httpTestingController.verify();
  });

  it(
    'test should wait for CounterService.getObservableValue',
    waitForAsync(() => {
      service
        .getObservableValue()
        .subscribe((value) => expect(value).toBe('observable value'));
    })
  );

  it(
    'test should wait for CounterService.getGirls',
    waitForAsync(() => {
      service
        .getGirls()
        .subscribe((value) => expect(value).toBeTruthy());

      const req = httpTestingController.expectOne('http://localhost:3000/girls');
      expect(req.request.method).toBe('GET');
      
      // flush this response
      req.flush(['Alicia', 'Tina', 'Michelle']);
    })
  );
});

This 是一个很好的博客post,可以帮助您进行 Http 测试。