Testing an AngularJS factory with Karma (Jasmine)

11,823

Solution 1

You need to call angular.injector:

'use strict';

(function() {
  describe('OfficerValidationService Spec', function() {

    var OfficerValidationService;

    beforeEach(function() {
      angular.module('darthvader');
    });

    beforeEach(inject(function() {
      var $injector = angular.injector(['darthvader']);
      OfficerValidationService = $injector.get('OfficerValidationService');
    }));

    it('is very true', function(){
      var output = OfficerValidationService.something();
      expect(output).toBeTruthy();
    });

  });
}());

Solution 2

To add to martynas' answer, here is a simplified version:

module() is the shorthand of angular.mock.module
inject() is the shorthand of angular.mock.inject (same as $injector)

'use strict';

(function() {
  describe('OfficerValidationService Spec', function() {
    var OfficerValidationService;

    beforeEach(module('darthvader'));
    beforeEach(inject(function (OfficerValidationService) {
      OfficerValidationService = OfficerValidationService;
    }));

     it('OfficerValidationService should exist', function() {
        expect(OfficerValidationService).toBeTruthy();
    });


  });
}());
Share:
11,823
chuckfinley
Author by

chuckfinley

Updated on June 23, 2022

Comments

  • chuckfinley
    chuckfinley almost 2 years

    I'm struggling with testing an AngularJS factory using Karma + Jasmine.

    I am unable to inject my factory to OfficerValidationService variable.

    What am i doing wrong?

    Note: the file is loaded properly

    Factory:

    'use strict';
    
    angular.module('darthvader').factory('OfficerValidationService', [function(){
    
      var OfficerValidationService = {};
    
      OfficerValidationService.something = function() {
        return true;
      };
    
      return OfficerValidationService;
    
    }]);
    

    Code:

    'use strict';
    
    (function() {
      describe('OfficerValidationService Spec', function() {
    
        var OfficerValidationService;
    
        beforeEach(function() {
          angular.module('darthvader');
        });
    
        beforeEach(module('darthvader', function($provide) {
          $provide.value('OfficerValidationService', OfficerValidationService);
        }));
    
        it('is very true', inject(function(OfficerValidationService){
          alert('=====' + OfficerValidationService + '=====');
          var output = OfficerValidationService.something();
          expect(output).toBeTruthy();
        }));
    
      });
    }());
    

    Output:

    Running "karma:unit" (karma) task
    INFO [karma]: Karma v0.12.17 server started at http://localhost:9876/
    INFO [launcher]: Starting browser PhantomJS
    INFO [PhantomJS 1.9.7 (Mac OS X)]: Connected on socket yc_qTseOCArRtZLAXSTZ with id 97647403
    ALERT: '=====undefined====='
    PhantomJS 1.9.7 (Mac OS X) OfficerValidationService Spec is very true FAILED
        TypeError: 'undefined' is not an object (evaluating 'OfficerValidationService.something')
            at /Users/chuck/Desktop/sandbox/dashboard.darthvader/test/karma/unit/services/officerValidationService.js:25
            at invoke (/Users/chuck/Desktop/sandbox/dashboard.darthvader/public/lib/angular/angular.js:3917)
            at workFn (/Users/chuck/Desktop/sandbox/dashboard.darthvader/public/lib/angular-mocks/angular-mocks.js:2155)
        undefined
    PhantomJS 1.9.7 (Mac OS X): Executed 28 of 28 (1 FAILED) (0.102 secs / 0.131 secs)
    
  • glepretre
    glepretre almost 10 years
    Why var $injector = angular.injector(['darthvader']); instead of beforeEach(inject(function($injector) {}); ?
  • Val Redchenko
    Val Redchenko about 8 years
    EDITED code example. I suppose having an explicit declaration may have been valuable to understand where it's coming from