Shailesh Vaishampayan
Shailesh Vaishampayan

Reputation: 1796

AngularJs Jasmine Unit test fails with Unexpected Request

Following is my myService.spec.js :

   'use strict';
    describe('myService', function () {
    var dependentService,dependentService1,rootScope,$q;
    beforeEach(module('myModule.myConfig'));
    beforeEach(module('myModule'));
    beforeEach(inject(function (_myService_, _$rootScope_,
                       _$q_,_dependentService1_,_dependentService_) {
    myService= _myService_;
    rootScope = _$rootScope_.$new();
    $q = _$q_;
    dependentService1= _dependentService1_;
    dependentService= _dependentService_;

    spyOn(dependentService1,'setPath');
    spyOn(dependentService,'get');
    spyOn($q,'all').and.callFake(function(){
        var deferred = _$q_.defer();
        if($q.all.calls.count() === 1){
            deferred.resolve([{path:'./abcd'}]);
        }else if($q.all.calls.count() === 2){
            deferred.resolve([{path:'./abcd','user':  {'userId':'xyz',
                                    'groups':['G1']}}]);
        }else{
            deferred.resolve({});
        }
        return deferred.promise;
    });
}));


it('should load path, information',function(){
    var promise = myService.load();
    rootScope.$apply();
    expect(dependentService.get).toHaveBeenCalled(); 
    expect(dependentService1.setPath).toHaveBeenCalledWith('./abcd');
});

 });

And here is my MyService.js

 'use strict';

 function    myService($q,dependentService1,dependentService){
var appConfigLoaded = false;
function _loadPath(){
    return dependentService.get(dependentService1.url);
}
return {
    load : function(){
        var loadPath = _loadPath(),
         finalDeferred = $q.defer();
         $q.all([loadPath ]).then(function (results) {
            var path = results[0].path ,
            user = results[0].user;
            dependentService1.setPath(path);
         $q.all([_loadDataPromise1(),_loadDataPromise2()]).then(function(results){
                finalDeferred.resolve(results);
            },function(reason){
                finalDeferred.reject(reason);
            });
         },function(reason){
             finalDeferred.reject(reason);
         });
        return finalDeferred.promise;
    }
  };

}
angular.module('myModule.myConfig').service('myService', MyService);

Following functions and service which holds them are omitted for brevity but they return promise. I have spied them as well just like I have spied other two services.

 loadDataPromise1() and loadDataPromise1()  

Now I get some error like Unexpected request GET with URL which points to some headers.template.html. But I am not even making any call to http to get such template nor any of the functions do. which ever call $http.get I have spied them.

I tried with

$httpBackend.flush();

but the same error occur. May be I am doing something basic thing in a wrong way.

If I remove $rootScope.apply() then error goes away. However .then() function in my service attached to first call to $q.all() is not called.

Any pointers to help me out?

Upvotes: 0

Views: 753

Answers (1)

ktharsis
ktharsis

Reputation: 3190

Do you have a default route with a templateURL in your application routing? You are probably running into this issue:
https://github.com/angular/angular.js/issues/2717

The workaround (which is annoying) is to put an expectGET for the templateURL in your beforeEach and then flush it.

$httpBackend.expectGET('path/to/template/defaulttemplate.html').respond(200, '');
$httpBackend.flush();

You can do it anywhere in there - I try and keep it at the top or bottom so it is obvious that is a workaround and not part of the testing code. Note you will have to put those lines in EVERY test file since the routing is part of app (not the module under test).

Upvotes: 2

Related Questions