AngularJS - 提供者和注入的 Karma 测试

AngularJS - Karma testing with providers and injections

我在为包含一些注入的提供程序编写单元测试用例时遇到了很多麻烦。

特定提供者是:

(function () {
angular
    .module('core.router', [])
    .provider('routerHelper', routerHelperProvider);

routerHelperProvider.$inject = ['$stateProvider', '$urlRouterProvider'];

/**
 * This method Initializes the Router Helper provider to be used by all modules
 *
 * @param $stateProvider
 * @param $urlRouterProvider
 */
function routerHelperProvider($stateProvider, $urlRouterProvider) {

    this.$get = routerHelperService;

    routerHelperService.$inject = ['$state'];

    /**
     * This method sets the methods to be used by the helper
     *
     * @param $state
     * @returns {Object}
     */
    function routerHelperService($state) {
        var hasOtherwise = false;

        return {
            configureStates: configureStates,
            getStates: getStates
        };

        /**
         * This method configures all the states to be used by the application
         *
         * @param {!String[]} states
         * @param {!String} otherwisePath
         */
        function configureStates(states, otherwisePath) {
            states.forEach(function (state) {
                //console.log("adding state", state.state, "with config", state.config);
                $stateProvider.state(state.state, state.config);
            });
            if (otherwisePath && !hasOtherwise) {
                hasOtherwise = true;
                $urlRouterProvider.otherwise(otherwisePath);
            }
        }

        /**
         * This method returns the states to be used by the application
         *
         * @return {Object}
         */
        function getStates() {
            return $state.get();
        }
    }
}  })();

基本单元测试是:

'use strict';

describe('core.router test', function () {

    // All Service injections
    var $urlRouterProvider, $stateProvider;

    // Mocks
    var m_url = function () {
    };
    var m_state = function () {
    };

    // Others
    var routerHelper, urlRouter, state, base;

    // Before statements
    beforeEach(module('core.router', function ($provide, _routerHelperProvider_) {
        $provide.value('$urlRouterProvider', m_url);
        $provide.value('$stateProvider', m_state);
        base = _routerHelperProvider_;
    }));

    // Starting the Factory
    beforeEach(inject(function (_routerHelper_, _$urlRouter_, _$state_) {
        routerHelper = _routerHelper_;
        urlRouter = _$urlRouter_;
        state = _$state_;
    }));

    describe('when testing it', function () {
        it('should return true', function () {

            //var abc = routerHelper.getStates();

            expect(1).toEqual(1);
        });
    });
});

我不断收到如下错误:

  • Error: [$injector:unpr] Unknown Provider: $stateProvider
  • Error: [$injector:unpr] Unknown Provider: $urlRouterProvider
  • Error: [$injector:unpr] Unknown Provider: routerHelperProvider

我尝试了几种不同的模块实例化和几种不同的注入,但我似乎无法让它工作。当我取出注入($stateProvider$urlRouterProvider$state)时,单元测试很简单。

因此,这将是解决方案,但会带来一些复杂性,因为提供者同时使用 $state 和 $stateProvider:

'use strict';

describe('core.router test', function () {

    // All Provider injections
    var $urlRouterProvider, $stateProvider;

    // Mocks
    var m_urlProvider = mockDataCore.urlRouterProvider();
    var m_stateProvider = mockDataCore.stateProvider();
    var m_state = mockDataCore.state();

    // Others
    var routerHelper, base;

    // Define the mock providers
    beforeEach(function(){
        module(function($provide){
            $provide.provider('$urlRouter', m_urlProvider);
            $provide.provider('$state', m_stateProvider);
        });
    });

    // Start the module with the internal mock
    beforeEach(function () {
        module('core.router', function ($provide) {
            $provide.value('$state', m_state);
        });
    });

    // Load the provider with module to be able to call its configuration methods
    beforeEach(function () {
        module(['routerHelperProvider', function (_$urlRouterProvider_, _$stateProvider_, _routerHelperProvider_) {
            $urlRouterProvider = _$urlRouterProvider_;
            $stateProvider = _$stateProvider_;
            base = _routerHelperProvider_;
        }]);
    });

    // Inject and start the provider
    beforeEach(function () {
        inject(['routerHelper', function (_routerHelper_, $state) {
            routerHelper = _routerHelper_;
        }]);
    });

    // test cases
    describe('when adding one state and no "otherwise"', function () {
        it('otherwise should not be called and state should be saved to state list', function () {

            spyOn(m_urlProvider, "otherwise");
            spyOn(m_stateProvider, "state");

            var simpleState = [{
                state : "home",
                config : {
                    url: "/home"
                }}];

            routerHelper.configureStates(simpleState);

            expect(m_urlProvider.otherwise).not.toHaveBeenCalled();
            expect(m_stateProvider.state).toHaveBeenCalledWith("home", {url: "/home"});
        });
    });

    describe('when getting the states', function () {
        it('should return the states', function () {

            spyOn(m_state, "get");

            var states = routerHelper.getStates();

            expect(m_state.get).toHaveBeenCalled();
        });
    });
});

模拟方法是:

var mockDataCore = (function () {
return {
    urlRouterProvider: urlRouterProvider,
    stateProvider: stateProvider,
    state: state
};

function urlRouterProvider() {
    return {
        otherwise: function () { /* void  */
        },
        $get: function () {  /* void  */
        }
    };
}

function stateProvider() {
    return {
        state: function () { /* void  */
        },
        $get: function () {  /* void  */
        }
    };
}

function state() {
    return {
        get: function () {
            return {};
        },
        go: function () {  /* void  */
        }
    };
}})();

当然,它没有涵盖该提供程序的所有测试,但其余测试非常简单..