onkami
onkami

Reputation: 9411

Mocking $httpBackend - how to handle "Unexpected request, No more request expected"?

I have a Jasmine test that is coded like this:

  it ("should send correct message to server to get data, and correctly set up scope when receiving it", function(){
    $httpBackend.when('GET', 'https://localhost:44300/api/projectconfiguration/12').respond(fakedDtoBase);
    $routeParams.projectId=fakeId; // user asks for editing project
    scope.$apply(function(){
        var controller=controllerToTest(); // so controller gets data when it is created
    });
    expect(scope.projectData).toEqual(fakedDtoBase);
});

and it kind of works, but I get the error:

Error: Unexpected request: GET views/core/main/main.html
No more request expected
    at $httpBackend (C:/SVN/src/ClientApp/client/bower_components/angular-mocks/angular-mocks.js:1207:9)
    at sendReq (C:/SVN/src/ClientApp/client/bower_components/angular/angular.js:7800:9)
    at $http.serverRequest (C:/SVN/src/ClientApp/client/bower_components/angular/angular.js:7534:16)
    (more stack trace)....

I do realise that I can mock every other call. But let's say I do not care what else my test wants to load as it may call few other things. How I can make sure that every other requests just "happen silently", maybe offering a single dummy response for everything else?

Upvotes: 36

Views: 58577

Answers (4)

Danny Mora
Danny Mora

Reputation: 21

you only need to add setTimeout and done property to your flush to prevent it

it('should get data in callback funcion', function (done) {
    $httpBackend.whenGET(/\/my-endpoint/).respond(mockDataResponse);

    apiFactory.getCurrencyFormat('en', function (res, err) {
        expect(res.a).to.deep.equal(generalMock.a);
        expect(res.b).to.deep.equal(generalMock.b);
    });

    setTimeout(function () {
        done();
        $httpBackend.flush();
    }, 200);
});

Upvotes: 0

ecoologic
ecoologic

Reputation: 10420

I think it's also important to notice that if you have a $digest(), your expectation should follow the $digest, like so:

_$rootScope_.$digest();
$httpBackend.when('GET', 'views/core/main/main.html').respond(fakedMainResponse);
// ...
$httpBackend.flush(); // And remember to flush at the end

Upvotes: 1

le0diaz
le0diaz

Reputation: 2508

For those who are using the httpBackend to mock http calls in EndToEnd tests or just mocking the entire http calls for the application the solution is to add the following code in the app config section (change the regexp according your template's location):

$httpBackend.whenGET(/^\/templates\//).passThrough();

Reference: https://docs.angularjs.org/api/ngMockE2E/service/$httpBackend

Tested with angularjs 1.4 to fix similar problem while integrating ui-router

Upvotes: 15

PrimosK
PrimosK

Reputation: 13918

Your test fails because a request is made which you haven't specified.

Try to add:

$httpBackend.when('GET', 'views/core/main/main.html').respond(fakedMainResponse);

Of course you should also define fakedMainResponse.

Please take a look also at the documentation (section Request Expectations vs Backend Definitions) which says:

Request expectations provide a way to make assertions about requests made by the application and to define responses for those requests. The test will fail if the expected requests are not made or they are made in the wrong order.

The second paramete of $httpBackend.when is actually a RegExp. So if you provide a RegExp that will match all other requests it should work.

Upvotes: 51

Related Questions