9

Angular 的$httpBackend 服务让你期待一个带有expectGET,expectPOST等(或只是expect)的 HTTP 请求。

我将如何编写一个测试,说“控制器不应该向这个端点发出请求(在这些条件下)”?

我在想类似的事情:

$httpBackend.when('/forbidden/endpoint').respond(function() {
  throw Error("Shouldn't be making a request to /forbidden/endpoint!");
});

这对我来说似乎有点hacky,但如果这是正常的做事方式,我可以接受。(但我对此表示怀疑。)

4

4 回答 4

12

我偶然发现了同样的问题。

解决方案是使用回调函数作为响应,并且在内部您可以expect(true).toBe(false)或在我看来更漂亮一些:

it ('should not trigger HTTP request', function() {
    var forbiddenCallTriggered = false;
    $httpBackend
      .when('/forbidden/endpoint')
      .respond(function() {
        forbiddenCallTriggered = true;
        return [400, ''];
      });

    // do whatever you need to call.

    $rootScope.$digest();
    $httpBackend.flush();

    // Let test fail when request was triggered.
    expect(forbiddenCallTriggered).toBe(false);
  });
于 2014-09-10T11:19:19.720 回答
5

对于这样的场景,我经常使用Jasmine 的 spyOn()函数。您可以监视 、 或自定义服务的功能$http$resource如下myServiceThatUsesHTTP所示):

spyOn(myServiceThatUsesHTTP, 'query');
// test, then verify:
expect(myServiceThatUsesHTTP.query).not.toHaveBeenCalled();
// or
expect(myServiceThatUsesHTTP.query.callCount).toBe(0);

当你spyOn()一个函数时,原来的函数被替换了。原始函数的代码未执行,这可能是好是坏(取决于您需要为测试做什么)。

例如,如果您需要$promise$http 或 $resource 返回的对象,您可以这样做:

spyOn($http, '$get').andCallThrough(); 
于 2014-03-14T16:09:15.370 回答
2

一种解决方案可能是检查是否$httpBackend.flush()抛出异常,因为应该没有什么要刷新的:

beforeEach(function() {
   $httpBackend.whenGET('/forbidden/endpoint');
   ...
   // call service method under test (that should not make $http call)
});

it('Should not call the endpoint', function() {
    expect($httpBackend.flush).toThrow();
});

需要注意的重要事项:我们使用whenand not expect,因为我们实际上并不期望调用。并且由于没有调用,$httpBackend.flush()会抛出异常:No pending request to flush。

于 2017-01-10T12:57:38.420 回答
0

$httpBackend未应用,因为$http在此测试中未进行调用。

相反,您可以注入$http您的测试,然后spyOn() $http直接:

beforeEach(fn () { 
  inject(function ($injector) {
    this.service = $injector.get('serviceOrControllerOrDirectiveBeingTested');
    this.$http = $injector.get('$http');
  }
});

接着

it('should ...', fn() {
  spyOn(this.$http, 'get');
  this.service.methodThatTriggersTheHttpCall();
  expect(this.$http.get).not.toHaveBeenCalled();
});
于 2015-11-13T17:48:13.493 回答