多个连续的 httpBackend 请求导致意外请求

Multiple sequential httpBackend requests cause unexpected request

我正在测试轮询资源直到满足条件的序列。

Book = $resource("/books/:id", {id: "@id"});

function poll(success) {
  Book.get({id:1}, function() {
    if (canStop) {
       success();
    } else {
       $timeout(poll, 1000);
    }

  });
};

下面的测试失败 Error: Unsatisfied requests: GET /user_workshops/1

describe('poll', function() {
  beforeEach(function() {
    $httpBackend.expectGET('/books/1').respond(200,{id:1});
    $httpBackend.expectGET('/books/1').respond(200,{id:1, newVal:1});

    poll(function() {
       successCalled = true;
    });

    $httpBackend.flush();
    $timeout.flush();

    canStop=true;

    $httpBackend.flush();
  });

  it('should call success when canStop is true', function() {
     expect(successCalled).toBe(true);
  });
});

我尝试重新安排测试顺序,将第二个 expectGET 放在第二个 httpBackend.flush() 之前,但随后我得到:

Error: Unexpected request: POST /books/1
No more request expected

经过一个小时的努力,我意识到 httpBackend 非常 特定于测试调用的顺序 - 期望值必须在调用 flush 之前设置,但在发出资源请求之前,当您调用 flush 时,您必须准确且仅发出预期的请求。

这意味着如果你想在顺序请求之间刷新,请求和期望的顺序必须完全是:

$httpBackend.expectGET('...')
resource.get();
$httpBackend.flush()
$httpBackend.expectGET('...')
resource.get();
$httpBackend.flush()
...
etc

所以对于上面的代码,如果我将顺序更改为:

describe('poll', function() {
  beforeEach(function() {
    $httpBackend.expectGET('/books/1').respond(200,{id:1});

    poll(function() {
       successCalled = true;
    });

    $httpBackend.flush();

    $httpBackend.expectGET('/books/1').respond(200,{id:1, newVal:1});

    $timeout.flush();
    canStop=true;

    $httpBackend.flush();
  });

  it('should call success when canStop is true', function() {
     expect(successCalled).toBe(true);
  });
});

您还可以在每次调用时重新准备 $httpBackend 方法。有点像:

var deleteMethod = function () {
    $httpBackend.when('DELETE', /.*/gi).respond(function(method, url, data) {
        deleteMethod(); // <--- See here method is rearmed
        return [200, 'OK', {}];
    });
}
deleteMethod();