Search code examples
angularjsunit-testingkarma-jasminespyon

Angular Jasmine spyOn $resource Unexpected request


I am unit testing an Angular controller which calls a service to get json data. I'm using Jasmine spyOn to spy on my service's query method like this:

spyOn facilitiesService, 'query'
    .and
    .callFake (success, error) ->
        deferred.promise.then success
        deferred.promise.catch error
        $promise: deferred.promise

I have defined a mock backend for running in the browser during development, that intercepts real REST calls, and uses $resource(path/to.json).query() to return fake data. Whenever I have the mock backend enabled, browser testing works fine, but my unit tests fail with unexpected request when I do scope.$digest(). How is the mock backend being called when I am spying on the method?

I would like this configuration to work with the mock backend specified so I can watch files and run unit tests before updating the application in the browser.

UPDATE:

http://plnkr.co/edit/hVc2YNnwUDNv7IHODOMD?p=preview

Here is a plunker I created that shows the behavior I'm seeing. Why is $httpBackend's whenGET method even being called?

I have seen other examples where they create a mock service that only contains empty methods to be spied on, but in that case, what is the point of spyOn's callFake if you already have a fake service, just put the callFake logic in the fake service's methods, and don't bother with spying.


Solution

  • In your mock expectation you are responding with :

    $resource('bagels.json2').query()
    

    but that's the thing again thriggering http request. The option is to add one more expectation before it:

    $httpBackend.whenGET('bagels.json2').respond(function() {return []});
    

    http://plnkr.co/edit/dkwl51kdMk6dADWs10bZ?p=preview

    After the comment below. Here is the solution where you should put expectation inside your test case.

    http://plnkr.co/edit/YimHnl2KztI7GET2MNWw?p=preview

    Also, you had (which was causing call to bagels.json2):

    $httpBackend.whenGET('bagels.json').respond($resource('bagels.json2').query());
    

    but you should have:

    $httpBackend.whenGET('bagels.json').respond(function() {
      $resource('bagels.json2').query()
      });