0

I try to unit test a simple factory that make a post request :

'use strict';

angular.module('app').factory('UserFactory', function ($http, $rootScope, $location) {
    return {
        'addUser': function (user) {
          $http.post('/api/user',
          {
            'user': user,
            'url': $location.path(),
            'title': $rootScope.title
          }).then(function(result){
            console.log(result);
          }).catch(function(err){
            console.log(err);
          });
        }
    };
});

And this is the unit test, which have to test the body passed to the Post request:

'use strict';

describe('UserFactory', function() {
  var factory;
  var httpBackend;
  var rootScope;
  var location;

  beforeEach(module('app'));

  beforeEach(inject(function($injector, $httpBackend, $rootScope, $location) {
    httpBackend = $httpBackend;
    rootScope = $rootScope;
    location = $location;
    factory = $injector.get('UserFactory');
    rootScope.title = 'Home';
    spyOn(location, 'path').and.callFake(function(param) {
     if(param) {
       return location;
     } else {
       return '/home';
     }
    });
  }));

  it('should correctly call the url /api/user with all informations provided in the body', function() {
    httpBackend.when('POST', '/api/user')
      .respond(200);
    httpBackend.expectPOST('/api/user', {'user': 'user test', 'url': '/home', 'title': 'Home'});
    factory.addUser({name: 'user test'});
    httpBackend.flush();
    httpBackend.verifyNoOutstandingExpectation();
    httpBackend.verifyNoOutstandingRequest();
  });
});

Unfortunately, the test throw: TypeError: undefined is not an object (evaluating 'current.$$route.title') when the httpBackend.flush() function is called, and I don't understand why...

Full Stack Trace:

TypeError: undefined is not an object (evaluating 'current.$$route.title') in C:/front/app/scripts/app.js (line 9)
        C:/front/app/scripts/app.js:9:14402
        $broadcast@C:/front/bower_components/angular/angular.js:17348:33
        C:/front/bower_components/angular-route/angular-route.js:647:36
        processQueue@C:/front/bower_components/angular/angular.js:15757:30
        C:/front/bower_components/angular/angular.js:15773:39
        $eval@C:/front/bower_components/angular/angular.js:17025:28
        $digest@C:/front/bower_components/angular/angular.js:16841:36
        flush@C:/front/bower_components/angular-mocks/angular-mocks.js:1779:45
        C:/front/test/unit/factories/user-factory-spec.js:86:22
Getz
  • 3,983
  • 6
  • 35
  • 52

1 Answers1

0

I found that the issue comes from the location mock:

spyOn(location, 'path').and.callFake(function(param) {
     if(param) {
       return location;
     } else {
       return '/home';
     }
    });

I didn't have a route called /home in my routeProvider configuration, so it failed. Replaced it with /, it works fine now.

Getz
  • 3,983
  • 6
  • 35
  • 52