如何在 AngularJS 应用程序中 mock/stub activate() 方法

How to mock/stub activate() method in AngularJS application

我目前正在开发一个大型 AngularJS 应用程序,该应用程序很大程度上基于出色的 AngularJS Styleguide by John Papa

他的一个建议是使用 activate() 方法作为每个控制器的一种引导程序。这使您的代码结构清晰,您立即知道引导程序从哪里开始。很多时候,我用它来加载数据(我更喜欢这个而不是路由解析)。

我面临的问题是我应该如何在下面的代码示例中对 methodUnderTest() 方法进行单元测试而不 运行 宁 activate() 方法。

(function() {
    'use strict';

    angular
        .module('myApp', [])
        .controller('ControllerUnderTest', ControllerUnderTest);

    ControllerUnderTest.$inject = [];

    /* @ngInject */
    function ControllerUnderTest() {
        var vm = this;

        // attach functions to vm
        vm.activate = activate;
        vm.methodUnderTest = methodUnderTest;

        // activate
        activate();

        function activate() {
            // controller start-up logic
        }

        function methodUnderTest() {
            // how to test this method, without running the activate() method
        }
})();

下面是我目前拥有的测试代码,但正如您所期望的那样,它总是 运行 activate() 方法(这不是我想要的)。

(function() {

    var scope, createController;

    beforeEach(module('myApp'));

    describe('ControllerUnderTest', function(){
        beforeEach(inject(function($rootScope, $controller) {
            scope = $rootScope.$new();

            createController = function() {
                return $controller('ControllerUnderTest', { 'scope': scope });
            };
        }));

        it('should be defined', function() {
            var controller = createController();
            expect(controller).toBeDefined();
        });

        it('should have a methodUnderTest', function() {
            var controller = createController();
            expect(controller.methodUnderTest).toBeDefined();
        });

    });
})();

如何在不使用 运行 方法 activate() 的情况下测试 ControllerUnderTest.methodUnderTest()

在模块单元测试中,您必须模拟所有超出测试范围的依赖项。

有点像:

beforeEach(module(function ($provide) {
    $provide.service("myService", function () {
        this.myMethod = function () {
            return "myValue";
        };
    });
}));