我通过ngController
将指令绑定到控制器,如下所示:
app.directive('myDirective', ['myService',
function(myService) {
return {
restrict: 'E',
replace: true,
scope: true,
require: "^ngController",
templateUrl: 'template.html',
link: {
pre: function (scope, elem, attrs, controller) {
scope.list = [];
myService.getData().then(function (response) {
scope.list = response.data;
});
},
post: function (scope) {
for (var rec = 0; rec < scope.list.length; rec++) {
if (scope.list[rec].key2 == 'd') {
// Do something here..
}
}
}
}
};
}
]);
使用样本控制器(因为该指令在多个地方使用):
app.controller('testController', [
function () {
var testCtrl = this;
}
]);
该指令的测试用例是:
describe('myDirective', function () {
var element, scope, ctrl;
beforeEach(angular.module('myModule'));
beforeEach(inject(function ($rootScope, $compile, $controller, $httpBackend) {
mockBackEnd = $httpBackend;
// Call to myService.getData()
mockBackEnd.expectGET('/module/service/api').respond({
values: [{key1: a, key2: b}, {key1: c, key2: d}]
});
element = angular.element('<div ng-controller="testController"><my-directive></my-directive></div>');
ctrl = $controller('testController', {});
scope = $rootScope.$new();
compile(element)(scope);
mockBackEnd.flush();
scope.$digest();
}));
it('Test for response', function () {
expect(scope.list.length).toBe(2);
});
});
我收到错误消息:PhantomJS 1.9.8 myDirective FAILED
TypeError: 'undefined' is not an object (evaluating 'scope.list.length')
进一步检查:在检查$digest()
发生的位置时,发现在post:
链接功能中,scope.list
对象显示为[]
,因为它应该是返回值来自服务。
该指令在模块中工作正常,但会在测试用例中引发问题。
我在这里做错了什么?在业力方面需要一些帮助。
答案 0 :(得分:0)
对不起@curlyreggie,当我查看你的代码时,我真的不明白为什么它如此复杂?
为什么不将数据作为数组或JSON对象传递给指令范围?
为什么要使用ng-controller指令?
无论如何,要在测试中向你的指令添加一些AngularJS函数,请使用angular.element()。
var compile = $compile; // is missing in your code
scope = $rootScope.$new();
var element = angular.element('<my-directive ng-controller="testController">Add all parameters, as you usually do in your html, if missing anything</my-directive>');
compile(element)(scope);
scope.$digest();
// Get the isolate scope for the directive
var isolatedScope = element.isolateScope();
console.log("isolatedScope", isolatedScope);
&&#39; mockBackEnd&#39;通常我这样注射:
beforeEach(inject(function ($rootScope, $compile, $controller, $injector) {
mockBackEnd = $injector.get('$httpBackend');
.....
}
不确定这是否有效,但至少我试图帮助你:)
答案 1 :(得分:0)
好吧,我使用了一些帮助from the community来解决它。
事实是,根据这里的评论/答案,我正在进行错误的测试。实际的测试用例设置应该是。
describe('myDirective', function () {
var element, scope, ctrl, directiveScope;
beforeEach(angular.module('myModule'));
beforeEach(inject(function ($rootScope, $compile, $controller, $httpBackend) {
mockBackEnd = $httpBackend;
// Call to myService.getData()
mockBackEnd.expectGET('/module/service/api').respond({
values: [{key1: a, key2: b}, {key1: c, key2: d}]
});
ctrl = $controller('testController', {});
scope = $rootScope.$new();
element = $compile(angular.element('<div ng-controller="testController"><my-directive></my-directive></div>'))(scope);
directiveScope = element.find('my-directive').scope();
scope.$digest();
mockBackEnd.flush();
}));
it('Test for response', function () {
expect(directiveScope.list.length).toBe(2);
});
我在这里摆弄父范围,指令的范围无法从外部访问。使用element.find().scope()
首先获取该范围并将其用于方便。
修改为新代码后,pre-link
和post-link
函数按预期执行。