How can I expect the HTTP request to NOT be executed?

Angular $ httpBackend service allows you to expect an HTTP request with expectGET , expectPOST , etc. (or just expect ).

How can I write a test that says: "The controller should NOT query this endpoint (under these conditions)"?

I thought something like:

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

It seems a bit hacked to me, but I'm fine if this is a normal way to do something. (But I doubt it.)

+6
source share
4 answers

I came across the same problem.

The solution would be to have a callback function as an answer, but inside you could expect(true).toBe(false) or, in my opinion, something more beautiful:

 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); }); 
+11
source

For such scenarios, I often use the Jasmine spyOn () function. You can track the functions of $http , $resource or a custom service (for example, myServiceThatUsesHTTP below):

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

When you spyOn() execute a function, the original function is replaced. The code for the original function is not executed, which can be good or bad (depending on what you need to do for the test).

For example, if you need the $promise object returned by $ http or $ resource, you can do this:

 spyOn($http, '$get').andCallThrough(); 
+5
source

One solution might be to check if $httpBackend.flush() thrown an exception since you don't have to hide anything:

 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(); }); 

It’s important to note: we use when , not expect , since we don’t actually expect the call to be made. And since there is no call, $httpBackend.flush() will throw an exception: There is no pending reset request.

+1
source

$httpBackend not applied because the call to $http does not work in this test.

Instead, you can enter $http in your test, and then spyOn() $http :

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

and then

 it('should ...', fn() { spyOn(this.$http, 'get'); this.service.methodThatTriggersTheHttpCall(); expect(this.$http.get).not.toHaveBeenCalled(); }); 
0
source

All Articles