angularjs 指令单元测试因 controllerAs、bindToController 和 isolateScope() 而失败
angularjs directive unit test fail with controllerAs, bindToController & isolateScope()
我正在尝试使用双向绑定 属性 (=) 对指令进行单元测试。该指令在我的应用程序中有效,但我无法进行测试双向绑定的单元测试。
几天来我一直在努力让它工作。我读过很多示例,这些示例使用了我想使用的一些但不是全部功能:controllerAs、bindToController 和 isolateScope()。 (忘掉 templateURL,我也需要它。如果我可以让它工作,我会添加它!:)
我希望有人能告诉我如何显示隔离范围中反映的父范围的变化。
这是一个包含以下代码的 plunkr:
http://plnkr.co/edit/JQl9fB5kTt1CPtZymwhI
这是我的测试应用程序:
var app = angular.module('myApp', []);
angular.module('myApp').controller('greetingController', greetingController);
greetingController.$inject = ['$scope'];
function greetingController($scope) {
// this controller intentionally left blank (for testing purposes)
}
angular.module('myApp').directive('greetingDirective',
function () {
return {
scope: {testprop: '='},
restrict: 'E',
template: '<div>Greetings!</div>',
controller: 'greetingController',
controllerAs: 'greetingController',
bindToController: true
};
}
);
这是规范:
describe('greetingController', function () {
var ctrl, scope, rootScope, controller, data, template,
compile, isolatedScope, element;
beforeEach(module('myApp'));
beforeEach(inject(function ($injector) {
rootScope = $injector.get('$rootScope');
scope = rootScope.$new();
controller = $injector.get('$controller');
compile = $injector.get('$compile');
data = {
testprop: 1
};
ctrl = controller('greetingController', {$scope: scope}, data);
element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>');
template = compile(element)(scope);
scope.$digest();
isolatedScope = element.isolateScope();
}));
// PASSES
it('testprop inital value should be 1', function () {
expect(ctrl.testprop).toBe(1);
});
// FAILS: why doesn't changing this isolateScope value
// also change the controller value for this two-way bound property?
it('testprop changed value should be 2', function () {
isolatedScope.testprop = 2;
expect(ctrl.testprop).toBe(2);
});
});
您必须更正测试指令的方式。您正在直接更改对象的 isolatedScope
,然后验证与您编译的 DOM
无关的 ctrl
对象。
基本上你应该做的是一旦你编译了一个带作用域的DOM(这里是<greeting-directive testprop="testprop"></greeting-directive>
)。因此该范围将包含已编译的 do 的上下文。总之可以发挥testprop
属性的价值。或 element.scope()
内将提供相同的东西。只要您更改 scope
/currentScope
中的任何值。您可以看到值在指令 isolatedScope
中得到更新。我还想提到的一件事是,当您使用 bindToController: true
执行 controllerAs
时,angular 添加 属性 并在 scope
中添加控制器别名,我们已验证 isolatedScope.greetingController.testprop
里面 assert
代码
describe('greetingController', function() {
var ctrl, scope, rootScope, controller, data, template,
compile, isolatedScope, currentScope, element;
beforeEach(module('myApp'));
beforeEach(inject(function($injector) {
rootScope = $injector.get('$rootScope');
scope = rootScope.$new();
controller = $injector.get('$controller');
compile = $injector.get('$compile');
data = { testprop: 1 };
ctrl = controller('greetingController', { $scope: scope }, data);
element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>');
template = compile(element)(scope);
scope.$digest();
currentScope = element.scope();
//OR
//currentScope = scope; //both are same
isolatedScope = element.isolateScope();
}));
// First test passes -- commented
it('testprop changed value should be 2', function() {
currentScope.testprop = 2; //change current element (outer) scope value
currentScope.$digest(); //running digest cycle to make binding effects
//assert
expect(isolatedScope.greetingController.testprop).toBe(2);
});
});
我正在尝试使用双向绑定 属性 (=) 对指令进行单元测试。该指令在我的应用程序中有效,但我无法进行测试双向绑定的单元测试。
几天来我一直在努力让它工作。我读过很多示例,这些示例使用了我想使用的一些但不是全部功能:controllerAs、bindToController 和 isolateScope()。 (忘掉 templateURL,我也需要它。如果我可以让它工作,我会添加它!:)
我希望有人能告诉我如何显示隔离范围中反映的父范围的变化。
这是一个包含以下代码的 plunkr:
http://plnkr.co/edit/JQl9fB5kTt1CPtZymwhI
这是我的测试应用程序:
var app = angular.module('myApp', []);
angular.module('myApp').controller('greetingController', greetingController);
greetingController.$inject = ['$scope'];
function greetingController($scope) {
// this controller intentionally left blank (for testing purposes)
}
angular.module('myApp').directive('greetingDirective',
function () {
return {
scope: {testprop: '='},
restrict: 'E',
template: '<div>Greetings!</div>',
controller: 'greetingController',
controllerAs: 'greetingController',
bindToController: true
};
}
);
这是规范:
describe('greetingController', function () {
var ctrl, scope, rootScope, controller, data, template,
compile, isolatedScope, element;
beforeEach(module('myApp'));
beforeEach(inject(function ($injector) {
rootScope = $injector.get('$rootScope');
scope = rootScope.$new();
controller = $injector.get('$controller');
compile = $injector.get('$compile');
data = {
testprop: 1
};
ctrl = controller('greetingController', {$scope: scope}, data);
element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>');
template = compile(element)(scope);
scope.$digest();
isolatedScope = element.isolateScope();
}));
// PASSES
it('testprop inital value should be 1', function () {
expect(ctrl.testprop).toBe(1);
});
// FAILS: why doesn't changing this isolateScope value
// also change the controller value for this two-way bound property?
it('testprop changed value should be 2', function () {
isolatedScope.testprop = 2;
expect(ctrl.testprop).toBe(2);
});
});
您必须更正测试指令的方式。您正在直接更改对象的 isolatedScope
,然后验证与您编译的 DOM
无关的 ctrl
对象。
基本上你应该做的是一旦你编译了一个带作用域的DOM(这里是<greeting-directive testprop="testprop"></greeting-directive>
)。因此该范围将包含已编译的 do 的上下文。总之可以发挥testprop
属性的价值。或 element.scope()
内将提供相同的东西。只要您更改 scope
/currentScope
中的任何值。您可以看到值在指令 isolatedScope
中得到更新。我还想提到的一件事是,当您使用 bindToController: true
执行 controllerAs
时,angular 添加 属性 并在 scope
中添加控制器别名,我们已验证 isolatedScope.greetingController.testprop
里面 assert
代码
describe('greetingController', function() {
var ctrl, scope, rootScope, controller, data, template,
compile, isolatedScope, currentScope, element;
beforeEach(module('myApp'));
beforeEach(inject(function($injector) {
rootScope = $injector.get('$rootScope');
scope = rootScope.$new();
controller = $injector.get('$controller');
compile = $injector.get('$compile');
data = { testprop: 1 };
ctrl = controller('greetingController', { $scope: scope }, data);
element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>');
template = compile(element)(scope);
scope.$digest();
currentScope = element.scope();
//OR
//currentScope = scope; //both are same
isolatedScope = element.isolateScope();
}));
// First test passes -- commented
it('testprop changed value should be 2', function() {
currentScope.testprop = 2; //change current element (outer) scope value
currentScope.$digest(); //running digest cycle to make binding effects
//assert
expect(isolatedScope.greetingController.testprop).toBe(2);
});
});