Search code examples
angularjsunit-testingkarma-jasmineangularjs-factory

angularjs - unit test, unable to call factory method


I'm having an hard time trying to call a factory method from karma unit test.

It says that the method that i'm trying to call (load()) does not exist.

Here's the code:

unitTest.js

describe('Data Factory', function() {
  var DataFactory, scope, spy;

  beforeEach(module('App'));

  beforeEach(inject(function($injector, $rootScope, _ZoneData_) {
    var DataFromjson;
    scope = $rootScope.$new();
    DataFromjson = _ZoneData_;
    return spy = spyOn(DataFromjson, 'load');
  }));

  return it('Should Load the right data from the json file', function() {
    var test;
    test = DataFactory;
    console.log(test);
    return expect(DataFactory).toBeDefined();
  });
});

and here's the factory code:

angular.module('services', ['ngResource']).factory('ZoneData', [
  '$http', '$stateParams', function($http, $stateParams) {
    var ZoneData;
    ZoneData = function(Data) {
      if (Data) {
        return this.setData(Data);
      }
    };
    ZoneData.prototype = {
      setData: function(Data) {
        return angular.extend(this, Data);
      },
      load: function(id) {
        var scope;
        scope = this;
        return $http.get('default-system.json').success(function(Data) {
          return scope.setData(Data.data);
        }).error(function(err) {
          return console.error(err);
        });
      },
      filtered: function() {
        var scope;
        scope = this;
        return $http.get('default-system.json').success(function(Data) {
          return angular.forEach(Data.data, function(item) {
            var urlZoneId;
            urlZoneId = parseInt($stateParams.zoneID);
            if (item.iID === urlZoneId) {
              return scope.setData(item);
            }
          });
        });
      }
    };
    return ZoneData;
  }
])

any help with a bit of explanation will be really really appreciated. Thanks


Solution

  • This is a problem with your factory implementation rather than the test. A factory in Angular is supposed to return an object and what you are returning is an object 'constructor' function.

    An easy solution would be to change the return value of your factory to be

    return new ZoneData();

    instead of returning

    return ZoneData;

    Please check this plunkr http://plnkr.co/edit/O8wnmgSQ8mc9t93jKDJ6?p=preview. I have created a stripped down version of the factory just to demonstrate the concept.

    Thanks.