Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ngMock $httpBackend should keep a list of the received calls to debug tests #10596

Closed
fabiosussetto opened this issue Dec 29, 2014 · 19 comments · Fixed by #15928
Closed

ngMock $httpBackend should keep a list of the received calls to debug tests #10596

fabiosussetto opened this issue Dec 29, 2014 · 19 comments · Fixed by #15928

Comments

@fabiosussetto
Copy link

Hi, I'm not sure if this is already possible, but I haven't found a way yet. In my unit tests I'm using $httpBacked to expect calls to an API. When the expectations fail, it would be useful to see a list of the actual calls, to see you .expectGET('..') failed because your code is calling the wrong url, or is sending the wrong data.

@pkozlowski-opensource
Copy link
Member

@fabiosussetto did you try, in your test:

afterEach(function() {
     $httpBackend.verifyNoOutstandingExpectation();
     $httpBackend.verifyNoOutstandingRequest();
});

AFAIK it should show failed expectations / additional requests. Docs here: https://docs.angularjs.org/api/ngMock/service/$httpBackend

@fabiosussetto
Copy link
Author

@pkozlowski-opensource yes indeed, and my test fails with this stacktrace:

Error: No pending request to flush !
        at Function.$httpBackend.flush (/Users/fabio/Code/waypoints/web_client/bower_components/angular-mocks/angular-mocks.js:1526:34)
        at Object.<anonymous> (/Users/fabio/Code/waypoints/web_client/src/tests/eventModelSpec.js:100:22)
    Error: Unsatisfied requests: PUT http://localhost:8000/be/rest/timelines/1/events/2
        at Function.$httpBackend.verifyNoOutstandingExpectation (/Users/fabio/Code/waypoints/web_client/bower_components/angular-mocks/angular-mocks.js:1559:13)
        at Object.<anonymous> (/Users/fabio/Code/waypoints/web_client/src/tests/eventModelSpec.js:24:22)

And my test was failing because I was calling the wrong url (specifically I was using the wrong id in the url) from my code under testing. I'd love to have a way to immediately see that the expected url was not hit, and instead the wrong url was.

@pkozlowski-opensource
Copy link
Member

I'd love to have a way to immediately see that the expected url was not hit, and instead the wrong url was.

Not sure what you are proposing, exactly, I'm afraid. Which API call you would expect to fail "immediately"?

@fabiosussetto
Copy link
Author

Sorry probably I haven't been very clear. Given my $httpBacked.expectGET() failed because I was calling the wrong url, I'd like to be able to do something along these lines:

console.log($httpBacked.calls)

and see a list of API calls received by the mocked http backend. That way I could see that I was calling the wrong URL.
At the moment I don't see a way to inspect the API calls I'm actually making during my unit tests.

From the failure message, I only know that for sure I didn't call the URL I was expecting to call, but then I'm in the dark, I don't know if I haven't call the API at all, or if I called it with the wrong URL (or wrong data, or headers).

@pkozlowski-opensource
Copy link
Member

@fabiosussetto are you sure that you've got this line in your test: $httpBackend.verifyNoOutstandingRequest();? This is the one that should give you a list of unexpected requests...

@fabiosussetto
Copy link
Author

http://plnkr.co/edit/zOSCORd25oAtccT6MZ6w?p=catalogue This is my actual test code. Here I'm expecting to call the wrong url, the failure I get is:

Error: No pending request to flush !
        at Function.$httpBackend.flush (/Users/fabio/Code/waypoints/web_client/bower_components/angular-mocks/angular-mocks.js:1526:34)
        at Object.<anonymous> (/Users/fabio/Code/waypoints/web_client/src/tests/eventModelSpec.js:48:22)
    Error: Unsatisfied requests: GET http://localhost:8000/be/rest/timelines/2/timeline
        at Function.$httpBackend.verifyNoOutstandingExpectation (/Users/fabio/Code/waypoints/web_client/bower_components/angular-mocks/angular-mocks.js:1559:13)
        at Object.<anonymous> (/Users/fabio/Code/waypoints/web_client/src/tests/eventModelSpec.js:24:22)

Which is fine, I know that I'm not doing a GET to http://localhost:8000/be/rest/timelines/2/timeline. The problem is that I am actually doing a GET to http://localhost:8000/be/rest/timelines/1/timeline instead (notice the wrong id the the url), but I don't see that in the error message. Am I doing something wrong in my test perhaps? If I change line 46 of my plunker to expect the right url (so http://localhost:8000/be/rest/timelines/1/timeline), then my test passes.

Btw I'm on angular 1.3.8.

Thanks a lot!

@fabiosussetto
Copy link
Author

I just tried to swap the two calls to be:

$httpBackend.verifyNoOutstandingRequest();
$httpBackend.verifyNoOutstandingExpectation();

so that it first checks for outstanding requests, but I get the same error message.

@fabiosussetto
Copy link
Author

Another update: I tried to remove my $httpBackend.flush(); and now I get the correct error message:
Error: Unsatisfied requests: PUT http://localhost:8000/be/rest/timelines/1/events/2
Then am I using flush() in the wrong way?

Sorry ignore the previous lines in this comment, it's not true, I get the same error message without the error "No pending request to flush !"

@pkozlowski-opensource
Copy link
Member

@fabiosussetto your plunker is not available (pasted a wrong link?) but I was just trying to replicate your issue and it seems to be correctly reporting both URLs on my end: http://plnkr.co/edit/IndYfHohO3KVznUEHdhL?p=preview

Error: Unexpected request: GET http://fooo.com Expected GET http://foo.com

Could you please share a plunker that shows your exact scenario?

@fabiosussetto
Copy link
Author

@pkozlowski-opensource try to click on the scripts.js file in my plunker and you should see my code, it's not a working example as it depends on a lot of other code, so I pasted just the spec.
Thanks for your example, I'm gonna have a look and see if it's because I'm doing something dodgy.

@pkozlowski-opensource
Copy link
Member

@fabiosussetto yeh, please provide a reduced code example that doesn't depend on any other code - otherwise it is next to impossible to progress on a given issue.

@fabiosussetto
Copy link
Author

@pkozlowski-opensource I understand, I'll post something more useful asap. Enjoy New Year's Eve tomorrow night :)

@Yvem
Copy link

Yvem commented Jan 22, 2015

I totally support more details when failing $httpBackend expectations.

Ex. the cryptic "Error: Unflushed requests: 4" : Why can't we access the unflushed requests ? At last their url to give us a lead ?

@thynctank
Copy link
Contributor

+1 for accessing unflushed requests

@turquoiseowl
Copy link

With v1.2.25, the installation of an $exceptionHandler can prevent $httpBackend's "Unexpected request ..." exception from propagating out to Jasmine. It doesn't seem to affect other $httpBackend-thrown exceptions.

@senthanal
Copy link

+1 for accessing unflushed requests, stacktrace as well.

@bostrom
Copy link

bostrom commented Jun 22, 2016

Agree.

Error: Unflushed requests: 2
    at Function.$httpBackend.verifyNoOutstandingRequest

isn't very informative. I'd like to know what the unflushed requests are.

@Narretz Narretz self-assigned this Feb 2, 2017
@lerzenit
Copy link

lerzenit commented Feb 3, 2017

+1.
In my case, I'm testing a factory depending on ngResource using a cache and want to test if the same request is done twice, and I have no way to know wich one is failing.

server.expectGET('/data').respond([item]);
server.expectGET('/data').respond([item]);

var resource = new resource('/data');

resource.query();
resource.invalidateCache();
resource.query();

And this is what I get

Error: Unsatisfied requests: GET /data
    at Function.$httpBackend.verifyNoOutstandingExpectation (public/js/angular.js:2290:13)
    at Function.$httpBackend.flush (public/js/angular.js:2269:18)
    at Object.<anonymous> (tests/frontend/share/cached-resource.factory.test.js:52:16)

I'm quite new to ngMock and $httpBackend so probably there is a better way to test this. However, I think $httpBackend should provide an error message with more information

jakewins added a commit to jakewins/angular.js that referenced this issue Apr 20, 2017
The current implementation of $httpBackend.verifyNoOutstandingRequest
gives an integer number describing how many requests are unflushed.

While it's superficially easy to solve test errors from that message
by simply adding an additional $httpBackend.flush(), if a developer
is truly not expecting the code to make further requests this is
not ideal.

This change explicitly prints out which additional requests remain
unflushed in the error message, helping her determine if the code
needs changing, or if an additional flush is appropriate.

Before this change:

    Unflushed requests: 1

After this change:

    Unflushed requests:
      GET /some

Closes angular#10596
jakewins added a commit to jakewins/angular.js that referenced this issue Apr 20, 2017
The current implementation of $httpBackend.verifyNoOutstandingRequest
gives an integer number describing how many requests are unflushed.

While it's superficially easy to solve test errors from that message
by simply adding an additional $httpBackend.flush(), if a developer
is truly not expecting the code to make further requests this is
not ideal.

This change explicitly prints out which additional requests remain
unflushed in the error message, helping her determine if the code
needs changing, or if an additional flush is appropriate.

Before this change:

    Unflushed requests: 1

After this change:

    Unflushed requests:
      GET /some

Closes angular#10596
Narretz pushed a commit that referenced this issue Apr 21, 2017
The current implementation of $httpBackend.verifyNoOutstandingRequest
gives an integer number describing how many requests are unflushed.

While it's superficially easy to solve test errors from that message
by simply adding an additional $httpBackend.flush(), if a developer
is truly not expecting the code to make further requests this is
not ideal.

This change explicitly prints out which additional requests remain
unflushed in the error message, helping her determine if the code
needs changing, or if an additional flush is appropriate.

Before this change:

    Unflushed requests: 1

After this change:

    Unflushed requests: 1
      GET /some

Closes #10596
Closes #15928
@Narretz
Copy link
Contributor

Narretz commented Apr 21, 2017

We just merged a commit into master / 1.6 that will make the following change:

Before this change:

Unflushed requests: 1

After this change:

Unflushed requests: 1
  GET /some

This doesn't cover all cases reported in this issue, only the most requested one: #10596 (comment)

Stack Traces for unexpected requests are tracked here: #12231

Narretz pushed a commit that referenced this issue Apr 21, 2017
The current implementation of $httpBackend.verifyNoOutstandingRequest
gives an integer number describing how many requests are unflushed.

While it's superficially easy to solve test errors from that message
by simply adding an additional $httpBackend.flush(), if a developer
is truly not expecting the code to make further requests this is
not ideal.

This change explicitly prints out which additional requests remain
unflushed in the error message, helping her determine if the code
needs changing, or if an additional flush is appropriate.

Before this change:

    Unflushed requests: 1

After this change:

    Unflushed requests: 1
      GET /some

Closes #10596
Closes #15928
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants