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