为什么HttpClient测试不需要done()函数?

时间:2018-03-02 13:57:27

标签: angular jasmine angular4-httpclient

这是官方文档中的简单示例。 https://angular.io/guide/http#expecting-and-answering-requests

it('can test HttpClient.get', () => {
  const testData: Data = {name: 'Test Data'};

  // Make an HTTP GET request
  httpClient.get<Data>(testUrl)
    .subscribe(data =>
      // When observable resolves, result should match test data
      expect(data).toEqual(testData)
    );

  // The following `expectOne()` will match the request's URL.
  // If no requests or multiple requests matched that URL
  // `expectOne()` would throw.
  const req = httpTestingController.expectOne('/data'); 

  // Assert that the request is a GET.
  expect(req.request.method).toEqual('GET');

  // Respond with mock data, causing Observable to resolve.
  // Subscribe callback asserts that correct data was returned.
  req.flush(testData);

  // Finally, assert that there are no outstanding requests.
  httpTestingController.verify();
});

我不明白为什么他们不在这里使用Jasmine的done函数。在我看来,它是异步操作,应该使用done回调进行测试。但与此同时,一切似乎都有效,所以对我来说真的很神奇。

1 个答案:

答案 0 :(得分:0)

好吧,在检查了MockBackend的工作原理,一些阅读和一些实验之后,我会尝试回答我自己的问题。

.get()模拟后端创建一个新请求并将其推送到内部数组中时,您的观察者函数是此请求的一部分。 .expectOne()方法从数组中提取此请求并返回测试。 .flush()向观察者提供所提供的数据并完成它。因此,通过一些假设,上面的代码可以用下一个方式重写

it('should work with observables', () => {
  const sub = new Subject();

  sub.subscribe((value) => {
    expect(value).toBe('a');
    // un-comment this line to see that this code really executes, 
    // test will fail
    // expect(1).toBe(2);
  });

  sub.next('a');
});

所以,基本上我们在这里有一系列嵌套回调,不要调用任何WebAPI并使用相同的observable:后端的.handle()方法创建它并.flush()调用.next()就可以了。

这就是为什么茉莉在这里不需要done()功能。