我有一个我正在尝试测试的键盘快捷键指令。它的目的是用事件数据触发$rootScope.$broadcast()
。在应用程序中它没有任何问题,但我不能让这个测试通过我想要的彻底。
(function(){
'use strict';
angular
.module('app.common')
.directive('keyboardShortcuts', keyboardShortcuts);
// @ngInject
function keyboardShortcuts($document, $rootScope){
return {
restrict: 'A',
link
}
function link(scope, el, attrs){
$document.bind('keypress', event => {
console.log('detected keypress');
$rootScope.$broadcast('keyboardShortcut', event);
scope.$digest(); // seems to make no difference
});
}
}
})();
对于单元测试,我添加了一个$scope.$on
处理程序来表明广播实际上正在制作和收听,但由于某些原因,间谍没有做到这一点。
describe('KeyboardShortcuts Directive', function(){
'use strict';
let $element;
let $scope;
let vm;
let $document;
let $rootScope;
const mockKeyboardEvent = {
type: 'keypress',
bubbles: true,
altKey: false,
ctrlKey: false,
shiftKey: false,
which: 106
}
beforeEach(module('app.common'));
beforeEach(inject(function(_$rootScope_, $compile, _$document_){
$element = angular.element('<div keyboard-shortcuts></div>');
$rootScope = _$rootScope_.$new();
$document = _$document_;
$scope = $rootScope.$new();
$compile($element)($scope);
$scope.$digest();
spyOn($rootScope, '$broadcast');
}));
////////////
it('should broadcast when a key is pressed', function(){
$scope.$on('keyboardShortcut', (event, data) => {
console.log('wtf!?');
expect(data.which).toBe(106);
});
$document.triggerHandler(mockKeyboardEvent);
$scope.$digest(); // seems to make no difference
expect($rootScope.$broadcast).toHaveBeenCalled();
});
});
这是控制台输出。您可以看到代码似乎正在起作用。
[15:33:57] Starting 'build:common:js'...
[15:33:58] Finished 'build:common:js' after 227 ms
[15:33:58] Starting 'test:common'...
20 09 2016 15:33:58.250:INFO [karma]: Karma v1.3.0 server started at http://localhost:9876/
20 09 2016 15:33:58.250:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
20 09 2016 15:33:58.253:INFO [launcher]: Starting browser PhantomJS
20 09 2016 15:33:58.797:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket /#37Fv2zndO5Z6XAZ8AAAg with id 3035140
..
LOG: 'detected keypress'
LOG: 'wtf!?'
PhantomJS 2.1.1 (Mac OS X 0.0.0) KeyboardShortcuts Directive should broadcast when a key is pressed FAILED
Expected spy $broadcast to have been called.
过去,当单元测试控制器时,我也遇到了这样的麻烦。我试图窥探那些在activate()
方法中运行的方法,这种方法是立即运行的(Papa风格),我能够通过将spyOn(...)
方法放在上面来让我的间谍工作/ strong>控制器实例化的位置。在这种情况下,我尝试将spyOn
放在'beforeEach'中的各种地方,似乎没有任何区别。
我还尝试了将expect..broadcast..beenCalled()
内容放在$on
处理程序中的明显解决方案,但这也不起作用,即使该断言通过并完全证明 <广播> 广播。
我有种感觉被监视的$ rootScope与注入和使用的$ rootScope不同,但我不知道它是怎么回事。
答案 0 :(得分:0)
适当的变量命名很重要。
这个
$rootScope
是Angular单元测试中广泛存在的错误之一。
问题在于,被称为spyOn($rootScope, '$broadcast');
的东西只是子范围,而不是根范围。看起来很容易忘记这一点,所以
$broadcast
某些范围内的存根 $rootScope = _$rootScope_;
$scope = $rootScope.$new();
方法。
应该是
$scope.$digest(); // seems to make no difference
和
<?php
$dataString = "03/10/2014";
$data = DateTime::createFromFormat("!m/d/Y", $dataString);
$turni = ["Sera", "Pomeriggio", "Mattina", "Notte", "Riposo"];
$numeroTurni = 10;
foreach (range(1, $numeroTurni) as $i) {
printf("%s %s<br />\n", $data->format("Y-m-d"), current($turni));
if (!next($turni)) {
reset($turni);
}
$data->add(new DateInterval("P1D"));
}
不应该存在,因为jQuery / jqLite事件与摘要周期无关。