Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I expect an HTTP request NOT to be made?

Angular's $httpBackend service lets you expect an HTTP request with expectGET, expectPOST, etc. (or just expect).

How would I write a test that says, "the controller should NOT make a request to this endpoint (under these conditions)"?

I was thinking something like:

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

That seems a bit hacky to me, but I'm fine with it if that's the normal way to do things. (But I doubt that.)

like image 995
Dan Tao Avatar asked Mar 14 '14 15:03

Dan Tao


2 Answers

I stumbled over the same issue.

The solution would be to have a callback function as response and inside you could expect(true).toBe(false) or in my opinion something a little bit 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);
  });
like image 156
lumio Avatar answered Oct 24 '22 19:10

lumio


For scenarios like this I often use Jasmine's spyOn() function. You can spy on functions of $http, $resource, or of a custom service (like myServiceThatUsesHTTP below):

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

When you spyOn() 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 that $http or $resource returns, you can do this:

spyOn($http, '$get').andCallThrough(); 
like image 37
Sunil D. Avatar answered Oct 24 '22 20:10

Sunil D.