【发布时间】:2016-11-15 16:13:35
【问题描述】:
好吧,我花了一天左右的时间寻找解决方案,但我不知道我是否更聪明,所以我崩溃了,决定问一下。另外,我对 Angular 还很陌生,因此请耐心等待。
我有一个从控制器定期调用的服务,用于从远程服务器检索更新的裁判分数。相当标准的东西。仅显示相关代码 - 没有错误处理程序和间隔取消等。
$app.service('ResultService', function($http) {
var self = this;
self.results = {};
self.getResults = function() {
return $http.get('/results').then(function(response) {
return $q.when(response.data).then(function(data) {
angular.copy(self.results, response.data);
};
};
};
});
$app.controller('ResultController', function($interval, resultService) {
var vm = this;
$interval(function() {
resultService.getResults().then(function(data) {
vm.results = data;
});
}, 1000);
});
到目前为止一切正常,一切都在浏览器中按预期运行。
现在开始测试。我想验证 getResults 函数是否接收并处理了更新,但是我正在努力执行必要的鸡牺牲以导致多次使用延期。我以为我可以这样做:
var deferred;
beforeEach(inject(function($q, httpBackend) {
deferred = $q.defer();
httpBackend.whenGET('/results').respond(deferred.promise);
});
it('updates results', inject(function($interval) {
deferred.resolve({some: 'data'});
scope.$digest();
httpBackend.flush();
$interval.flush(1200);
// This works fine
expect(resultsService.results).toEqual({some: 'data'});
deferred.resolve({other: 'data'});
scope.$digest();
httpBackend.flush();
$interval.flush(1200);
// But this of course does not.
expect(resultsService.results).toEqual({other: 'data'}); // fails
});
现在看来,deferred 的 promise 只能解决一次。所以我的问题是,如何在每次测试迭代时为服务的 $http.get() 调用提供新数据?我尝试了各种方法,但都没有成功:
- 创建了一个本身返回一个延迟承诺的延迟。如此疯狂。
- 尝试使用新响应重新设置 httpBackend.whenGET()。这没有效果。
- 在间隔迭代之间的测试内创建了一个新的 deferred。不用说这失败了,因为原来 deferred 的 promise 已经设置好了。
- 从 whenGET() 返回一个静态值,并直接操作该值。不幸的是,虽然这“有效”,但它看起来相当老套,并导致另一项测试(预期会被拒绝)失败。
那么我错过了什么?这里有什么诀窍?我对替代解决方案(不使用延迟)以及任何可以使用代码原样清除我眼中的刻度的东西持开放态度。
【问题讨论】:
标签: angularjs testing jasmine deferred inject