如何在指令的单元测试中检查是否已调用$ emit?
我的指示相当简单(为了说明):
angular.module('plunker', [])
.directive('uiList', [function () {
return {
scope: {
lengthModel: '=uiList',
},
link: function (scope, elm, attrs) {
scope.$watch('lengthModel', function (newVal) {
scope.$emit('yolo');
});
}
}
}])
所以每次uiList属性改变时,都会发出事件。
我的单元测试代码如下:
describe('Testing $emit in directive', function() {
var scope;
var element;
//you need to indicate your module in a test
beforeEach(function () {
module('plunker');
inject(function ($rootScope, $compile) {
scope = $rootScope.$new();
scope.row= 1;
spyOn(scope,'$emit');
element = angular.element('<ul id="rows" ui-list="row">');
$compile(element)(scope);
});
});
it('should emit', function() {
scope.$digest();
scope.row = 2;
scope.$digest();
expect(scope.$emit).toHaveBeenCalledWith("yolo");
});
});
这总是会让我错误地说明范围。$ emit从未被调用过。 范围有问题吗?有人可以帮忙吗?
答案 0 :(得分:7)
你的指令创建了一个独立的范围,它正在调用$emit
,所以你需要监视这个范围;)
describe('Testing $emit in directive', function() {
var scope;
var element;
var elementScope;
beforeEach(module('plunker'));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
scope.row = 1;
element = angular.element('<ul id="rows" ui-list="row">');
$compile(element)(scope);
scope.$digest();
elementScope = element.scope();
}));
it('should emit', function() {
// arrange
spyOn(elementScope, '$emit');
// act
scope.$apply(function() {
scope.row = 2;
});
// assert
expect(elementScope.$emit).toHaveBeenCalledWith("yolo");
});
});
答案 1 :(得分:0)
我不确定glepetre是如何工作的(不确定它确实如此)。对我来说没有。问题是指令在命令范围内运行registerNewReturnedType(Class c)
,因此它在内部创建的范围和$new
有些不同。您可以查看他们的element.scope()
字段。因此,窥探$id
的范围无济于事。我有一个微笑的问题,不得不做一个小技巧,让它工作。
我的测试来了:
element.scope()
所以诀窍就是在 beforeEach(inject(function () {
scope = $rootScope.$new();
scope.$apply(function () {
scope.field = null;
scope.name = 'nolength';
});
spyOn(scope, '$new').and.returnValue(scope);
spyOn(scope, '$emit');
var element = angular.element('<my-directive name="name" field="field" title="\'Title\'" ></my-directive>');
noLengthValidation = $compile(element)(scope);
scope.$apply();
elementScope = element.scope();
}));
上模拟$new
函数,所以不是在场景后面创建一个新的范围而是把事情弄得乱七八糟,它会自行返回!测试本身来了:
scope
指令中调用 it('The directive should not react on string length if no max-chars attribute presented', function () {
scope.$apply();
noLengthValidation.isolateScope().field = 'fieldisssssssveeeeerryyyyyylooooooonnnngggggggggggggggggggggggggggg';
scope.$apply();
expect(scope.$emit).toHaveBeenCalledWith('ON_MORE_AWASOME_EVENT', 'nolength');
});
的部分。以防万一:
$emit