jasmine.clock().tick()不能与$timeout和debounce一起工作,但可以与setTimeou
jasmine.clock().tick() does not work with $timeout and debounce, but works fine with setTimeout
下面我有3个函数做完全相同的事情。每个都使用不同的方式调用setTimeout
, delay1()
直接使用setTimeout
, delay2()
使用angularjs $timeout
, delay3()
使用lodash debounce
。它们都很好。
当我使用Jasmine进行测试时,问题出现了。setTimeout
可以很好地使用jasmine.clock().tick()
方法,但$timeout
和debounce
不能
我有兴趣和Jasmine一起工作。我知道我可以使用$timeout.flush()
与angularjs,但$timeout
和setTimeout
给我的问题在我的代码的其他地方,我使用它与传单地图。《Debounce》与传单搭配得很好。
我在这里创建了一个plunker: plnkr,在这里您将看到$timeout
和debounce测试没有通过,而setTimeout测试通过。
有办法可以解决这个问题吗?由于
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.name = 'World';
$scope.delayed1 = function(){
setTimeout(function(){
$scope.name = "Hello world by setTimeout";
},500)
}
$scope.delayed2 = function(){
$timeout(function(){
$scope.name = "Hello world by $timeout";
},500)
}
$scope.delayed3 = function(){
_.debounce(function(){
$scope.name = "Hello world by debounce";
},500)
}
});
规范describe('Testing a Hello World controller', function() {
var $scope = null;
var ctrl = null;
//you need to indicate your module in a test
beforeEach(module('plunker'));
beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
ctrl = $controller('MainCtrl', {
$scope: $scope
});
}));
it('should say hallo to the World', function() {
expect($scope.name).toEqual('World');
});
it('should say Hello world by setTimeout', function() {
jasmine.clock().install();
$scope.delayed1();
jasmine.clock().tick(600);
expect($scope.name).toEqual('Hello world by setTimeout');
jasmine.clock().uninstall();
});
it('should say Hello world by timeout', function() {
jasmine.clock().install();
$scope.delayed2();
jasmine.clock().tick(600);
expect($scope.name).toEqual('Hello world by timeout');
jasmine.clock().uninstall();
});
it('should say Hello world by debouce', function() {
jasmine.clock().install();
$scope.delayed3();
jasmine.clock().tick(600);
expect($scope.name).toEqual('Hello world by debouce');
jasmine.clock().uninstall();
});
});
Jasmine中的时钟仅在您直接测试setInterval()
或setTimeout()
函数时才会工作,因为它只是专门模拟这些函数以同步运行。我相信有一个pull request for Jasmine来模拟Date对象,这将允许测试像_.debounce()
这样的函数而不模拟它,但我不记得是否合并在一起。
要测试_.debounce()
,您必须模拟它以同步运行,最好是作为间谍,或者您可以直接覆盖该函数。以下是我发现对我有用的方法:
spyOn(_, 'debounce').and.callFake(function (func) {
return function () {
func.apply(this, arguments);
};
});
现在对_.debounce()
的调用将同步运行,测试应该成功完成。当然,你仍然必须使用$timeout.flush()
。
我更新了你的活塞与这些变化:http://plnkr.co/edit/KXmwcf1faUNf8nlqPeyd
来自lodash
的debounce函数使用Date
对象。使用jasmine
模拟Date
对象,如下所示:
jasmine.clock().install();
jasmine.clock().mockDate();
jasmine.clock().tick(1000); // trigger the debounce
来源:https://jasmine.github.io/2.9/introduction.html section-Mocking_the_Date
除了@JDWardle的答案之外,您可能还想为debounce cancel方法创建一个间谍。
spyOn(_, 'debounce').and.callFake(function (func) {
var mockDebounce = function () {
func.apply(this, arguments);
};
mockDebounce.cancel = jasmine.createSpy('cancel');
return mockDebounce;
});
- 如何在php中创建一个函数,该函数与文本区域一起工作,通过输入类似[color:red]的内容来打印具有等效颜色的文本
- document.title函数可以't设置它与php一起工作
- :focus:一起活跃,不在firefox上工作
- Javascript无法与Onsen一起在Cordova工作
- "此网站似乎使用滚动链接定位效果.这可能不能很好地与异步平移一起工作;
- 有没有办法把它们串在一起,这样它们基本上可以同时工作
- 非常简单的js测试;Don’不要和Minko一起工作
- 无法使我的文本参数与我的查询一起工作
- 为什么Angularjs验证don't与输入[type=“number”]一起工作
- 无法使vash 0.8.0与express 4.12.3一起工作
- 如何使Angular JS控制器与指令一起工作
- 无法使autocompletion与bootstrap和php代码点火器一起工作
- 注入的元素和jQuery脚本.如何让他们一起工作
- 安全地包装JS文件,这样当它们连接在一起时,它们仍然可以工作
- 两个独立工作的javascript函数,但不能一起工作
- 角度和砖石一起工作
- Node http-proxy-middleware 不能与本地服务器一起工作
- 我需要在单击时运行两个函数.即使嵌套在一起,我也无法让它们都工作
- jQuery脚本不想一起工作
- page.js使examples/hash与hashbang:true一起工作