Venu
Venu

Reputation: 184

Angular factory testing with Karma Jasmine. Says UnKnown provider

This is my angular code

    var app = angular.module('FleetTask', ['ui.router']);

    app.constant('settings', {
        ApiURL: 'http://localhost/FleetTask.API',
        MsgDuration: 4000,
        ProductURL: '/api/product', 
        ProductGroupURL: '/api/productgroup',
        DataAreaURL: '/api/dataarea'
    });

    app.factory('ProductGroupFactory', ['$http', 'settings', function ($http, settings) {

        return {
            getProductGroupList: function () {
                return $http.get(settings.ApiURL + settings.ProductGroupURL);
            },
            getProductGroupByID: function (id) {
                return $http.get(settings.ApiURL + settings.ProductGroupURL + "/" + id);
            },
            saveProductGroup: function (productGroup) {
                return $http.put(settings.ApiURL + settings.ProductGroupURL, productGroup);
            },
            deleteProductGroup: function (id) {
                return $http.delete(settings.ApiURL + settings.ProductGroupURL + "/" + id);
            },
            getProductList: function () {
                return $http.get(settings.ApiURL + settings.ProductURL);
            },
            getDataAreaList: function (lookup) {
                return $http.get(settings.ApiURL + settings.DataAreaURL + "/dataarealist/" + lookup);
            }
        };

    }]);

    app.controller('ProductGroupController', function ($scope, ProductGroupFactory, $rootScope, settings) {

        function init(pageIndex) {
            $rootScope.pageTitle = "Product Group";

            // Complete functionality       

        };

        init();
    });

This is my test spec:

    describe('FleetTask', function () {
        beforeEach(function () {
            module('FleetTask');
            module('ui.router');
        });

        describe('ProductGroupFactory', function () {

            var scope, controller, productGroupFactory, settings;

            beforeEach(inject(function ($injector, $rootScope, $controller, $provide) {

                scope = $rootScope.$new();
                settings = $injector.get('settings');

                productGroupFactory = {
                    save: jasmine.createSpy()
                };

                $provide.value('ProductGroupFactory', productGroupFactory);

            }));


            it('Access Factory', function () {
                expect(settings).toBeDefined();
            });
        });
    });

This is the error I am getting

enter image description here

Error says UnKnown provider. Looks like I am not doing right way of injecting factory. 'settings' service got injected correctly, but not the factory. Help me to find out right process to inject factory. Thanks

Answer: Derived test spec I have made out of answers.

     describe('FleetTask', function () {

        var scope, controller, pgFactory, constants, httpBackend;

        beforeEach(function () {
            module('FleetTask');
            module('ui.router');
            module('angulartics');
            module('angulartics.google.analytics');

            inject(function (_settings_, $injector, $controller, _$rootScope_) {

                $rootScope = _$rootScope_;
                scope = $rootScope.$new();
                constants = _settings_;

                pgFactory = function () {
                    return $injector.get('ProductGroupFactory');
                };

                httpBackend = $injector.get('$httpBackend');
                httpBackend.whenGET(constants.ApiURL + constants.ProductURL).respond(function (data) { scope.products = data; });
                httpBackend.expectGET(constants.ApiURL + constants.ProductGroupURL);
                httpBackend.expectGET(constants.ApiURL + constants.DataAreaURL + "/dataarealist/0");

                controller = $controller;
                controller('ProductGroupController', { '$scope': scope });
            });

        });

        it('Check if settings service is defined', function () {
            expect(constants).toBeDefined();
        });

        it('Check if ProductGroupFactory is defined', function () {
            expect(pgFactory).toBeDefined();
        });

        it('Check if controller is defined', function () {       
            expect(controller).toBeDefined();
        });

        it('Access Controller', function () {
            expect(scope.error).toBe('');
        });

        it('Check if controller is defined', function () {
            var prds = scope.products;
            var len = prds.length;

            expect(len).toBe(0);
        });

    });

Upvotes: 1

Views: 2882

Answers (1)

PSL
PSL

Reputation: 123739

You need to access $provide as a part of module specification, it can't be injected. i.e

beforeEach(module("FleetTask", function ($provide) {
     productGroupFactory = jasmine.createSpyObj('productGroupFactory', ['save']);
      $provide.value('ProductGroupFactory', productGroupFactory);
}));



beforeEach(inject(function (_settings_, $rootScope, $controller) {
     scope = $rootScope.$new();
     settings = _settings_;
     //...
 }));


 it('Access Factory', function () {
     expect(settings).toBeDefined();
  });

Upvotes: 5

Related Questions