在角度中,如何在我的指令中调用范围函数?
我使用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;
答案 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()是否实际被调用,甚至更多 - 如果它做了它应该做的事情。