【问题标题】:Angular controller not initialized in jasmine test茉莉花测试中未初始化角控制器
【发布时间】:2014-03-09 13:34:48
【问题描述】:

我在使用 Angular ui-router 为 AngularJS 应用程序编写 jasmine 测试时遇到了问题。我的服务和应用程序在测试中正确初始化,但控制器无法正常启动。我已经将有问题的应用程序排除在外,并将问题简化为一个表现相同行为的简单控制器示例。这是实际的测试代码:

describe('Test', function() {
    var async = new AsyncSpec(this);
    var scope = {};

    beforeEach(angular.mock.module('TestApp'));

    beforeEach(angular.mock.inject(function($rootScope, $state, $templateCache) {
        scope.$rootScope  = $rootScope;
        scope.$state      = $state;

        $templateCache.put('start.html', '<div class="start"></div>');
    }));

    async.it('Test that TestCtrl is initialized', function(done) {
        scope.$rootScope.status = { done: false };
        scope.$rootScope.$on('$stateChangeSuccess', function(event, state, params) {
            expect(scope.$rootScope.status.done).toBe(true);
            done();
        });
        scope.$state.transitionTo('start', {}, { notify: true });
        scope.$rootScope.$apply();
    });
});

这是完整的可运行文件test

应用程序被正确初始化,ui 路由器能够将应用程序转换到正确的状态,但控制器没有被初始化。我需要路由器初始化控制器,因为路由器将关键配置传递给它们。我想避免在测试中重复该配置。

我一定错过了什么,但是什么?感谢您的任何意见,谢谢!

【问题讨论】:

    标签: javascript angularjs jasmine angular-ui-router


    【解决方案1】:

    您需要使用 $controller 服务在您的测试中实例化您的控制器并将其传递给您的范围。比如……

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

    请注意,我还将 $rootScope.done 的声明移至 TestCtrl 以防止有关 $rootScope.done 未定义的错误。这是小提琴...

    http://jsfiddle.net/C8QtB/3/

    【讨论】:

    • 谢谢,但不幸的是,这并不能完全解决我的问题。我需要让 ui-router 实例化控制器。这是因为路由器配置了控制器(准确解析参数)。所以我想在测试中使用路由器,以避免在每次测试中重复控制器配置。不考虑这个问题是我的坏事。我编辑了问题以反映这一点。
    • 您将不得不按照我描述的使用 $controller 服务的方式进行操作。您不会在每次测试中都重复它。它在每个钩子之前,所以它会在每次测试之前自动运行,这是合适的方式。测试应该是独立的,而不是依赖以前的测试来成功。您的路线不会在单元测试中实例化您的控制器,因为您实际上并没有导航到任何路线。如果您想测试路由实例化控制器,您应该在集成测试中进行。模拟路由解析参数提供的值并将其注入到您的测试中。
    • 实际上,我正在尝试在该测试中导航;请参阅 $state.transitionTo() 调用。该调用最终会加载模板文件,但控制器并未初始化。当然,我不必为每个测试都这样做,但我肯定会为应用程序的不同部分提供单独的测试文件,我最终会在每个文件中复制初始化代码,或者提出一个基本测试我将在每个测试中使用的排序。我宁愿 ui-router 为我做这件事。
    • 我认为您的测试超出了单元测试的范围。如果你想测试状态的变化,你应该在集成测试中进行。单元测试应该单独测试单个组件。这意味着您测试单个“单元”或从角度上测试单个控制器、服务或指令。在单元测试中更改状态意味着您在一个单元测试中测试至少 2 个控制器。另外,为什么还要测试路由器实例化控制器呢?此功能是 angular 的一部分,并且已经在 angular 测试中进行了测试。你应该相信它。只是我的两分钱......
    • 关于超出单元测试范围的公平点。我对测试转换并不感兴趣。但 mereley 正在寻找一种机制来配置控制器,就像它们在实际用例中一样。感谢您的讨论!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    相关资源
    最近更新 更多