【发布时间】:2015-09-29 21:05:09
【问题描述】:
我有一个具有一些缓存逻辑的服务方法:
model.fetchMonkeyHamById = function(id)
{
var that = this;
var deferred = $q.defer();
if( that.data.monkeyHam )
{
deferred.resolve( that.data.monkeyHam );
return deferred.promise;
} else {
return this.service.getById( id).then( function(result){
that.data.monkeyHam = result.data;
});
}
};
我知道如何使用 $httpBackend 来强制返回模拟数据。现在,当我明确设置数据时,如何强制它解析(然后测试结果)?
我想在控制器 then() 函数中测试结果:
MonkeyHamModel.fetchMonkeyHamById(this.monkeyHamId).then( function() {
$scope.currentMonkeyHam = MonkeyHamModel.data.monkeyHam;
});
然后我的测试我想显式设置数据(所以它从内存“缓存”而不是 httpBackend 加载)
MonkeyHamModel.data.monkeyHam = {id:'12345'};
MonkeyHamModel.fetchMonkeyHamById( '12345');
// How to "flush" the defer right here like I would have flushed httpBackend?
expect( $scope.currentMonkeyHam.id ).toEqual('12345'); //fails because it is not defined yet since the $q never resolved
其中 $scope 只是我的控制器的范围,但为了简洁起见,这里称为 $scope。
更新:
建议的答案不起作用。我需要该函数返回一个承诺,而不是一个承诺的结果:
model._monkeyHams = {} // our cache
model.fetchMonkeyHamById = function(id){
return model.monkeyHams[id] || // get from cache or
(model.monkeyHams[id] = this.service.getById(id).then(function(result){
return result.data;
}));
};
以下要求您已经接触过服务器。我在前端(currentMonkeyHam)或其他任何东西上创建了一个模型,并且在第一次 POST(不必要的 GET 请求)之后不加载它。我只是使用当前的模型。所以这是行不通的,它需要至少去服务器一次。因此,您可以看到为什么我创建了自己的 deferred。如果我们没有,我想使用当前模型数据或从服务器获取它。我需要两种途径来回报承诺。
var cache = null;
function cachedRequest(){
return cache || (cache = actualRequest())
}
【问题讨论】:
标签: angularjs unit-testing jasmine promise angular-promise