如何测试angularjs指令窥视函数调用? [英] How do I test angularjs directive to spy on the function call?
问题描述
code以下执行,但抱怨element.popover不会被调用。我似乎无法找出问题是什么。
感谢您提前帮助。
指令:
angular.module('指令',[])。指令(酥料饼',函数($ HTTP){ 返回{
限制:'C', 链接:功能(范围,元素,属性){
element.bind('鼠标悬停',函数(E){
$ http.get(someurl+ attr.chatid +以.json)。成功(功能(数据){
element.popover({内容:data.firstName ++ data.lastName});
});
});
}
}
})
茉莉花测试:
用户严格描述('指令',函数(){
beforeEach(模块('指示'));
描述('酥料饼',函数(){
变量$范围,编译,位置,$ httpBackend,榆树; beforeEach(注(函数($ rootScope,$编译_ $ httpBackend_){
$范围= $ rootScope $新的()。
编译= $编译;
$ httpBackend = _ $ httpBackend_;
榆树= angular.element('< I类=弹出了数据放置=顶数据chatid =testChatId>< / I>');
编译(榆树)($范围内); })); 它('应该调用element.popover()',函数(){
$ httpBackend.expectGET('someurl / testChatId.json')。
回应([{姓:'测试',名字:'用户'}]); spyOn(榆树,'酥料饼')andCallThrough()。 elm.trigger('鼠标悬停');
$ httpBackend.flush(); 期待(elm.popover).toHaveBeenCalled();
});
});
});
输出:
铬26.0(苹果机)指令酥料饼应该调用element.popover()失败
以被称为预计间谍酥料饼。
以被称为预计间谍酥料饼:错误。
更新:
我是不是能够解决您的具体问题。主要是因为我无法获得角的种子会/有人到永远,但我想我会做我的答案更完整。
有2种方式来解决,一般这样的问题:
- 在一个比其他功能间谍被一些触发
事件/中介 - 创建该对象之前,函数的原型间谍。换句话说:
spyOn(MyObjectNamespace.Class.prototype,'functionToSpyOn')
后来才恢复,你应该罚款。
我只角有些眼熟,但都遇到类似的问题。
解决方法1
您可以只分离出的功能,而不是匿名指定它。这有助于专门测试功能,并避免所有的角的东西。
解决方案2
有时与框架,这是不可能的。这里的主要问题是,你是间谍自身附加太晚,参考丢失或被覆盖。
测试:
描述('指令',函数(){
beforeEach(模块('指示'));
描述('酥料饼',函数(){
变量$范围,编译,位置,$ httpBackend,榆树; beforeEach(注(函数($ rootScope,$编译_ $ httpBackend_){
$范围= $ rootScope $新的()。
编译= $编译;
$ httpBackend = _ $ httpBackend_;
榆树= angular.element('< I类=弹出了数据放置=顶数据chatid =testChatId>< / I>');
编译(榆树)($范围内); })); 它('应该调用element.popover()',函数(){
VAR popoverFunction = $ .fn.popover;
$ httpBackend.expectGET('someurl / testChatId.json')。
回应([{姓:'测试',名字:'用户'}]); spyOn($ FN,酥料饼')andCallThrough()。 elm.trigger('鼠标悬停');
$ httpBackend.flush(); 期待($ fn.popover).toHaveBeenCalled();
//恢复酥料饼,用兴农的新生力量,而不是在这里恢复
$ .fn.popover = popoverFunction
});
});
});
您可以使用兴农茉莉。兴农有被你干掉第一个和最后一行的spy.restore功能。在我自己的测试,我放在第一行和间谍创造了beforeEach并在afterEach恢复。
Code below executes but complains about element.popover not being invoked. I can't seem to figure out what the issue is.
Thanks for help in advance.
directive:
angular.module('directives', []).
directive('popOver', function ($http) {
return {
restrict:'C',
link: function (scope, element, attr) {
element.bind('mouseover', function (e) {
$http.get("someurl" + attr.chatid + ".json").success(function (data) {
element.popover({content: data.firstName + " " + data.lastName });
});
});
}
}
})
Jasmine test:
'user strict'
describe('directives', function() {
beforeEach(module('directives'));
describe('popOver', function() {
var $scope, compile, location, $httpBackend, elm;
beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
$scope = $rootScope.$new();
compile = $compile;
$httpBackend = _$httpBackend_;
elm = angular.element('<i class="pop-over" data-placement="top" data-chatid="testChatId" > </i>');
compile(elm)($scope);
}));
it('should call element.popover()', function() {
$httpBackend.expectGET('someurl/testChatId.json').
respond([ {firstName: 'test', lastName: 'user'}]);
spyOn(elm, 'popover').andCallThrough();
elm.trigger('mouseover');
$httpBackend.flush();
expect(elm.popover).toHaveBeenCalled();
});
});
});
Output:
Chrome 26.0 (Mac) directives popOver should call element.popover() FAILED
Expected spy popover to have been called.
Error: Expected spy popover to have been called.
Update:
I wasn't able to solve your specific problem. Mostly because I couldn't get angular-seed going/it was taking forever, but I thought I'd make my answer more complete.
There are 2 ways to solve this problem in general:
- Spy on a function other than the one being triggered by some event/intermediary
- Spy on the prototype of the function before the object is created. In other words:
spyOn(MyObjectNamespace.Class.prototype, 'functionToSpyOn')
Afterwards just restore and you should be fine.
I am only vaguely familiar with angular, but have experienced similar problems.
Solution 1
You can just separate out the function rather than specifying it anonymously. This helps test your functionality specifically and avoid all the angular stuff.
Solution 2
Sometimes with frameworks this isn't possible. The main problem here is that your spy is attaching itself too late and the reference is lost or gets overridden.
Test:
describe('directives', function() {
beforeEach(module('directives'));
describe('popOver', function() {
var $scope, compile, location, $httpBackend, elm;
beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
$scope = $rootScope.$new();
compile = $compile;
$httpBackend = _$httpBackend_;
elm = angular.element('<i class="pop-over" data-placement="top" data-chatid="testChatId" > </i>');
compile(elm)($scope);
}));
it('should call element.popover()', function() {
var popoverFunction = $.fn.popover;
$httpBackend.expectGET('someurl/testChatId.json').
respond([ {firstName: 'test', lastName: 'user'}]);
spyOn($.fn, 'popover').andCallThrough();
elm.trigger('mouseover');
$httpBackend.flush();
expect($.fn.popover).toHaveBeenCalled();
//restore popover, use sinon's restore fn instead here
$.fn.popover = popoverFunction
});
});
});
You can use Sinon with Jasmine. Sinon has a spy.restore function that gets rid of the first and last line for you. In my own tests I've placed the first line and the spy creation in a beforeEach and the restore in an afterEach.
这篇关于如何测试angularjs指令窥视函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!