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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |