angularjs – 如何通过父元素测试Component Bindings的更改?
发布时间:2020-12-17 07:02:29 所属栏目:安全 来源:网络整理
导读:我有一个像下面这样的组件,并希望测试$onChange方法在绑定myBinding更改时的作用. 我整个上午都试过,但找不到办法解决这个问题. angular .module('project.myComponent',[]) .component('myComponent',{ bindings: { myBinding: '' },template: 'div{{$ctrl.
|
我有一个像下面这样的组件,并希望测试$onChange方法在绑定myBinding更改时的作用.
我整个上午都试过,但找不到办法解决这个问题. angular
.module('project.myComponent',[])
.component('myComponent',{
bindings: {
myBinding: '<'
},template: '<div>{{$ctrl.result}}</div>',controller: myComponentController
});
function myComponentController($filter,someService) {
var ctrl = this;
ctrl.result = 0;
$ctrl.$onChange = function (changes) {
if(angular.isDefined(changes.myBinding)) {
if(angular.isDefined(changes.myBinding.currentValue)) {
if(angular.isDefined(changes.myBinding.currentValue != changes.myBinding.previousValue)) {
myService.doSomething(changes.myBinding.currentValue).then(
function(data) {
ctrl.result = changes.myBinding.currentValue * 3;
}
);
}
}
}
}
}
我希望我的测试表现得像是更改绑定值的组件父级. require('angular-mocks');
describe('myComponment',function() {
var element,scope;
beforeEach(inject(function(_$rootScope_,_$compile_) {
}));
fit('should display the controller defined title',function() {
// prepare test and set myBinding to 10
expect(component.result).toBe(30);
});
});
那可能吗?怎么样? 解决方法
测试AngularJS组件与测试指令没有太大差别.
要测试控制器的方法/属性,可以使用 下面是使用 angular.module('myApp',[])
.component('myComponent',{
bindings: {
myBinding: '<'
},controller: 'myComponentController'
})
.controller('myComponentController',['$filter','myService',function myComponentController($filter,myService) {
var ctrl = this;
ctrl.$onInit = onInit;
ctrl.$onChanges = onChanges;
function onInit() {
ctrl.result = ctrl.myBinding;
}
function onChanges(changes) {
if (angular.isDefined(changes.myBinding)) {
if (angular.isDefined(changes.myBinding.currentValue)) {
if (!angular.equals(changes.myBinding.currentValue,changes.myBinding.previousValue)) {
myService.doSomething(changes.myBinding.currentValue).then(
function (data) {
ctrl.result = data;
}
);
}
}
}
}
}])
.service('myService',['$timeout',function ($timeout) {
return {
doSomething: function (x) {
return $timeout(function () {
return x * 3;
},500);
}
};
}]);
/*
TEST GO HERE
*/
describe('Testing a component controller',function() {
var $scope,ctrl,$timeout,myService;
beforeEach(module('myApp',function ($provide) {
}));
beforeEach(inject(function ($injector) {
myService = $injector.get('myService');
$timeout = $injector.get('$timeout');
}));
describe('with $compile',function () {
var element;
var scope;
var controller;
beforeEach(inject(function ($rootScope,$compile) {
scope = $rootScope.$new();
scope.myBinding = 10;
element = angular.element('<my-component my-binding="myBinding"></my-component>');
element = $compile(element)(scope);
controller = element.controller('myComponent');
scope.$apply();
}));
it('should render template',function () {
expect(element[0].innerText).toBe('10'); //initial
$timeout.flush(); //onchanges happened and promise resolved from the service
//undefined -> 10
expect(element[0].innerText).toBe('30');
});
it('should reflect to changes',function () {
spyOn(myService,"doSomething").and.callThrough();
scope.myBinding = 15; //change the binding
scope.$apply(); //we need to call $apply to pass the changes down to the component
$timeout.flush();
expect(myService.doSomething).toHaveBeenCalled(); // check if service method was called
expect(controller.result).toBe(45); // check controller's result value
});
})
});
.as-console-wrapper {
height:0;
}
<!DOCTYPE html>
<html>
<head>
<!-- jasmine -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.js"></script>
<!-- jasmine's html reporting code and css -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine-html.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/boot.js"></script>
<!-- angular itself -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<!-- angular's testing helpers -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-mocks.js"></script>
</head>
<body>
<!-- bootstrap jasmine! -->
<script>
var jasmineEnv = jasmine.getEnv();
// Tell it to add an Html Reporter
// this will add detailed HTML-formatted results
// for each spec ran.
jasmineEnv.addReporter(new jasmine.HtmlReporter());
// Execute the tests!
jasmineEnv.execute();
</script>
</body>
</html>
您还可以使用 ctrl = $componentController('myComponent',{$scope: scope},{ myBinding: 10 });
ctrl.$onInit();
要测试$onChanges钩子,您需要传递一个“正确”构造的更改对象作为参数: angular.module('myApp',controller: 'myComponentController'
})
.controller('myComponentController',myService) {
var ctrl = this;
ctrl.$onInit = onInit;
ctrl.$onChanges = onChanges;
function onInit() {
ctrl.result = ctrl.myBinding;
}
function onChanges(changes) {
if (angular.isDefined(changes.myBinding)) {
if (angular.isDefined(changes.myBinding.currentValue)) {
if (!angular.equals(changes.myBinding.currentValue,changes.myBinding.previousValue)) {
myService.doSomething(changes.myBinding.currentValue).then(
function (data) {
ctrl.result = data;
}
);
}
}
}
}
}])
.service('myService',function ($timeout) {
return {
doSomething: function (x) {
return $timeout(function () {
return x * 3;
},500);
}
};
}]);
/*
TEST GO HERE
*/
describe('Testing a component controller',function () {
var $scope,myService;
beforeEach(module('myApp',function ($provide) {
}));
beforeEach(inject(function ($injector) {
myService = $injector.get('myService');
$timeout = $injector.get('$timeout');
}));
describe('with $componentController',function () {
var scope;
var controller;
beforeEach(inject(function ($rootScope,$componentController) {
scope = $rootScope.$new();
scope.myBinding = 10;
controller = $componentController('myComponent',{myBinding: 10});
controller.$onInit();
}));
it('should reflect to changes',function () {
spyOn(myService,"doSomething").and.callThrough();
controller.$onChanges({myBinding: {currentValue: 15,previousValue: 10}});
$timeout.flush(); // resolve service promise
expect(myService.doSomething).toHaveBeenCalled(); // check if service method was called
expect(controller.result).toBe(45); // check controller's result value
});
})
});
.as-console-wrapper {
height:0;
}
<!DOCTYPE html>
<html>
<head>
<!-- jasmine -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.js"></script>
<!-- jasmine's html reporting code and css -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine-html.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/boot.js"></script>
<!-- angular itself -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<!-- angular's testing helpers -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-mocks.js"></script>
</head>
<body>
<!-- bootstrap jasmine! -->
<script>
var jasmineEnv = jasmine.getEnv();
// Tell it to add an Html Reporter
// this will add detailed HTML-formatted results
// for each spec ran.
jasmineEnv.addReporter(new jasmine.HtmlReporter());
// Execute the tests!
jasmineEnv.execute();
</script>
</body>
</html>
P.S.:$onChange不是组件生命周期钩子的有效名称.它should be (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
