如何在指令UT中模拟所需的指令控制器

时间:2013-05-13 02:19:29

标签: javascript angularjs angularjs-directive

根据AngularJS doc a /指令控制器是:

  

在预链接阶段之前实例化,如果它们按名称请求,则与其他指令共享(请参阅require属性)。这允许指令相互通信并增强彼此的行为。

在UI视图由容器和窗口小部件组成的情况下,这听起来很棒且有用,窗口小部件的链接功能可以通过声明性方法require:^cotnainerDirective在容器指令控制器中传递。这提供了另一种回调容器行为的方法,而不是依赖于事件的通信。

例如,一个需要容器控制器的widget指令如下:

angular.module('platform').directive('widget', [ function ( ) {
    return {
        restrict: 'E',
        transclude: true,
        require: '?^container',
        replace: true,
        scope: {
            layout: '=',
            model: '='
        },
        templateUrl: 'js/modules/platform/templates/form-tmpl.html',
        link: function (scope, element, iAttrs, requiredCtrl) {
            if(requiredCtrl && requiredCtrl.fooMethod){
                ....
            }
        }
    };
}]);

如果窗口小部件位于容器内,链接函数内的代码将执行额外的工作。代码工作正常。但是,当进行单元测试widget指令时,很难想到一个很好的方法来发送一个模拟容器指令控制器,因为它不是通过Angular $ injector服务注入的。

可能,我需要从容器角度编写UT,但这在某种程度上涉及引导容器指令所需的太多准备工作。以前有人遇到这个,可以在这里分享一些好处吗?

2 个答案:

答案 0 :(得分:0)

事实证明,如果我想对widget指令进行单元测试,它必须与容器松散地分离,在这种情况下使用“require”不是一个好主意,因为它实际上使得widget指令紧紧依赖于容器。我已经改变了我的设计以使用事件驱动的通信btw小部件和容器,这样我就可以简单地模拟事件监听器来监视UT中的widget指令发送的事件。

答案 1 :(得分:0)

您可以在测试中定义<fake-parent> HTML元素,然后在containerControllerMock键下将$containerController添加到其数据存储中。我在这里解释了这种单独测试子指令的方法:https://demisx.github.io/angularjs/unit-testing/2014/10/28/unit-testing-angular-child-directive-that-requires-parent.html