我有一个带有手表的控制器,它使用来自lodash的debounce延迟过滤列表500ms。
$scope.$watch('filter.keywords', _.debounce(function () {
$scope.$apply(function () {
$scope.filtered = _.where(list, filter);
});
}, 500));
我正在尝试编写一个Jasmine测试,模拟输入未找到的过滤器关键字,然后找到找到的关键字。
我最初的尝试是在为关键字指定新值后使用$ digest,我认为这是因为去抖动而无效。
it('should filter list by reference', function () {
expect(scope.filtered).toContain(item);
scope.filter.keywords = 'rubbish';
scope.$digest();
expect(scope.filtered).not.toContain(item);
scope.filter.keywords = 'test';
scope.$digest();
expect(scope.filtered).toContain(item);
});
所以我尝试使用$ timeout,但这也不起作用。
it('should filter list by reference', function () {
expect(scope.filtered).toContain(item);
$timeout(function() {
scope.filter.keywords = 'rubbish';
});
$timeout.flush();
expect(scope.filtered).not.toContain(item);
$timeout(function() {
scope.filter.keywords = 'test';
});
$timeout.flush();
expect(scope.filtered).toContain(item);
});
我还尝试给$ timeout一个大于debounce设置的500ms的值。
其他人如何解决这个问题?
编辑:我找到了一个解决方案,即将期望包装在$ timeout函数中,然后在范围内调用$ apply。
it('should filter list by reference', function () {
expect(scope.filtered).toContain(item);
scope.filter.keywords = 'rubbish';
$timeout(function() {
expect(scope.filtered).not.toContain(item);
});
scope.$apply();
scope.filter.keywords = 'test';
$timeout(function() {
expect(scope.filtered).toContain(item);
});
scope.$apply();
});
我仍然有兴趣知道这种方法是否最好。
答案 0 :(得分:4)
这是一种糟糕的做法。你应该使用角度特定的去抖动,例如使用$ timeout而不是setTimeout的this。这样,你可以做到
$timeout.flush();
expect(scope.filtered).toContain(item);
并且规范将按预期传递。
答案 1 :(得分:1)
我已经用过了:
beforeEach(function() {
...
spyOn(_, 'debounce').and.callFake(function (fn) {
return function () {
//stack the function (fn) code out of the current thread execution
//this would prevent $apply to be invoked inside the $digest
$timeout(fn);
};
});
});
function digest() {
//let the $watch be invoked
scope.$digest();
//now run the debounced function
$timeout.flush();
}
it('the test', function() {
scope.filter.keywords = ...;
digest();
expect(...);
});
希望有所帮助
答案 2 :(得分:-1)
使用spyOn替换_.debounce,请检查此链接。 http://gotoanswer.stanford.edu/?q=Jasmine+test+does+not+see+AngularJS+module