单元测试 angularjs 指令的事件广播
Posted
技术标签:
【中文标题】单元测试 angularjs 指令的事件广播【英文标题】:Unit testing angularjs directives's event broadcast 【发布时间】:2015-07-29 10:52:49 【问题描述】:我以前从未测试过我的 angularjs 指令,我为当前公司编写的指令也是使用事件将指令传达给指令和服务。
于是我写了一个指令,例如一个搜索指令。
<m-search />
这个指令广播"searchbox-valuechanged"
事件和密钥,现在我必须为它编写测试。
'use strict';
describe('<m-search>', function()
beforeEach(module('hey.ui'));
var rootScope;
beforeEach(inject(function($injector)
rootScope = $injector.get('$rootScope');
spyOn(rootScope, '$broadcast');
));
it("should broadcast something", function()
expect(rootScope.$broadcast).toHaveBeenCalledWith('searchbox-valuechanged');
);
);
更新 在输入发生变化时,
<input class="m-input m-input--no-border" type="search" placeholder="Search"
ng-model="ctrl.searchValue"
ng-model-options="debounce: 100"
ng-change="ctrl.onChange(search: ctrl.searchValue)">
它调用指令控制器中的方法
vm.onChange = function (searchValue)
$rootScope.$broadcast('searchbox-valuechanged', data: searchValue);
;
如何测试广播?
【问题讨论】:
searchbox-valuechanged
事件在哪里处理?在指令之外?
是的,searchbox-valuechanged
是使用 $rootScope 广播的,所以 $rootScope
是唯一的依赖项,指令完全解耦。
什么触发了广播?您需要在测试代码中复制它
好的,我会编辑问题,顺便说一句,这会触发广播。 'ng-change="ctrl.onChange(search: ctrl.searchValue)">' +
是模板的一部分,在指令控制器中,它调用 ctrl.onChange
【参考方案1】:
这就是我的做法......
describe('m-search directive', function()
var ctrl, // your directive's controller
$rootScope; // a reference to $rootScope
beforeEach(function()
// bootstrap your module
module('hey.ui');
inject(function($compile, _$rootScope_)
$rootScope = _$rootScope_;
// see https://docs.angularjs.org/api/ngMock/function/angular.mock.inject#resolving-references-underscore-wrapping-
// create an instance of your directive
var element = $compile('<m-search></m-search')($rootScope.$new());
$rootScope.$digest();
// get your directive's controller
ctrl = element.controller('mSearch');
// see https://docs.angularjs.org/api/ng/function/angular.element#methods
// spy on $broadcast
spyOn($rootScope, '$broadcast').and.callThrough();
);
);
it('broadcasts searchbox-valuechanged on change', function()
var searchValue = search: 'search string';
ctrl.onChange(searchValue);
expect($rootScope.$broadcast).toHaveBeenCalledWith(
'searchbox-valuechanged', data: searchValue);
);
);
您会注意到这根本不依赖于您的指令模板。我不相信模板功能属于单元测试领域。这最好留给量角器进行 e2e 测试。单元测试是关于测试您的组件的 API 以确保它们按预期执行。
【讨论】:
找不到变量 $rootscope @JoeyHipolito 糟糕,我忘了在beforeEach
之外提供它。现已修复以上是关于单元测试 angularjs 指令的事件广播的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jasmine 对包含私有超时的单元测试 Angularjs 指令
当单元测试时,AngularJS指令中的scope方法不是函数
离子单元测试中广播的意外 $locationChangeStart 和 $locationChangeSuccess 事件