在角度我怎样才能测试在我的指令中调用范围函数?

时间:2016-07-20 11:26:43

标签: javascript angularjs unit-testing testing jasmine

在角度中,如何在我的指令中调用范围函数?

我使用jasmine,karma runner和使用Angular版本1的js单元测试。

这是我的指令代码:

x = 0

这是我的单元测试:

angular.module("myApp.directives")
    .directive("test", ["$rootScope", function($rootScope) {
        return {
            restrict: "E",
            scope: {
                "figures": "="
            },
            templateUrl: "templates/components/test.html",
            link: function(scope) {

                scope.init = function() {
                    if (scope.figures !== undefined) {
                        for (let i = 0; i < scope.figures.length; i++) {
                            scope.figures[i].isModalVisible = false;
                        }
                    }
                };

                scope.init ();
            }
        };
    }]);

这是我目前得到的错误:&#34;已经调用了预期的间谍初始化。&#34;

1 个答案:

答案 0 :(得分:2)

首先:您的spyOn(scope, "init")expect(scope, "init")都是在错误的范围内执行的。您可以将init 内部指令添加到隔离范围,因此它应该是spyOn(otherScope, "init")expect(otherScope, "init")

其次,第一点仍然会失败。 :)原因是init()只在调用link()时执行一次,这将发生在你的beforeEach块中的范围。$ digest()上 - 但是你不在那里提供数据。你在测试的后期提供它的时候已经太晚了,因为指令已经在第一个摘要周期被链接了,并且你的测试中第二个scope.$digect()不会调用init()。要解决此问题,您需要推迟第一个摘要周期,直到您在测试用例中准备好所有数据为止。

第三,首先需要将html元素附加到DOM,然后再编译它。在这么简单的情况下,它可能会起作用,但是如果元素中的任何内容需要父元素上的某些指令(即内部的指令具有类似require: "^something"的配置),那么编译将失败:没有包含所需实体的父元素你的新元素,直到你真正将它插入DOM。

<强>更新

您无法像这样测试这种情况。安装间谍的适当时间点是在向示波器添加init()之后但在调用它之前,但问题是此时间点位于指令内,因为函数调用在添加后立即触发功能范围。由于这一点不在测试代码中,因此您无法以这种方式编写测试。

但让我们从另一个角度考虑这种情况。 init()做什么?它会重置数据阵列上的标志。因此,您可以在 true之前使用$digest()初始化这些标记,并且可以在调用$ digest之后检查这些标记是否已重置 ()。这样,您可以轻松准备数据并断言结果。您的测试将能够清楚地告诉您init()是否实际被调用,甚至更多 - 如果它做了它应该做的事情。