[英]Unit testing asynchronous Angular directive
这个问题的第一次迭代: 使用$ http对Angular指令进行单元测试
我创建了一个指令,该指令绑定到输入时,会在修改DOM之前通过调用服务来响应模糊/键入事件。 该服务依赖$ http,因此是异步的。 我已经为服务编写了功能单元测试,但是在我的生命中,我无法为指令编写工作测试。
describe('SignupForm directives', function () {
var form, // el to which directive is applied
scope,
userService,
el;
beforeEach(function() {
module('signupform.directives');
});
beforeEach(function() {
inject(function ($injector, $rootScope, $compile, $q, $timeout) {
scope = $rootScope.$new();
el = $compile('<input id="username" type="text" name="username" ng-model="user.username" sg-valid-username />')(scope);
userService = $injector.get('userService');
scope.user = { username: 'test_username' };
spyOn(userService, 'checkIfUserExists');
});
});
it('Directive fires on blur', function() {
scope.$digest();
// build blur event and fire it
var blurEvent = $.Event('blur');
angular.element(el).triggerHandler(blurEvent);
expect(userService.checkIfUserExists).toHaveBeenCalled();
});
});
我已经证明使用调试器可以调用该服务(userService.checkIfUserExists)。 只是Expect()在此之前发生,并且未通过测试。
不过,我不知道如何异步编写此代码。 Jasmine 2.0的done()概念令人难以置信,否则userService不需要回调即可传入。
我该如何处理?
在$timeout
使用$timeout
而不是setTimeout
,以便可以在单元测试中手动刷新挂起的超时。
.directive('sgValidUsername', ['$timeout', 'userService', function ($timeout, userService) {
return {
restrict: 'A',
link: function(scope, element) {
var promise;
element.on('blur keyup', function(e) {
$timeout.cancel(promise);
promise = $timeout(function() {
userService.checkIfUserExists();
}, 1000);
});
}
}
}])
在您的单元测试中,在el.triggerHandler('blur')
$timeout.flush()
之后调用$timeout.flush()
以手动触发超时回调(该调用称为checkIfUserExists
)。
it('Directive fires on blur', function() {
el.triggerHandler('blur');
$timeout.flush();//Flush pending timeouts
expect(userService.checkIfUserExists).toHaveBeenCalled();
});
有关完整的工作示例,请参见此plnkr 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.