我有一个函数A
,它是控制器内部的私有函数。函数A
仅在控制器内部一次使用:
$scope.$on('callA', function () {
A();
});
在A()
内部,有一个执行操作的服务调用:
this.aPromise = myService.AsyncTask(var1, var2);
this.aPromise.promise.then(function (response) {
...
$scope.$applyAsync(function() {
...
});
}
这是我到目前为止尝试过的:
it('should perform task A', function () {
var promise;
promise = $q.$resolve();
spyOn(myService, 'AsyncTask').and.returnValue(promise);
$rootScope.$broadcast('callA'); // call the function
});
但是,我收到以下错误: TypeError:无法读取未定义的属性'then'。我将其追溯到以下行:this.aPromise.promise.then(function (response) {
我正在尝试测试
...
行代码。我如何确保茉莉花在运行expect()
之前等待承诺解决?
答案 0 :(得分:0)
您应该尝试使用$q.defer()
而不是$q.$resolve()
it('should perform task A', function (done) { // use the done argument
var mockResponse = {msg: "Success"};
var defer = $q.defer();
spyOn(myService, 'AsyncTask').and.returnValue(defer);
$rootScope.$broadcast('callA'); // call the function
$rootScope.$apply(function(){
defer.resolve(mockResponse); // manually resolve the promise
});
defer.promise.then(function(response){
expect(response.msg).toEqual(mockResponse.msg);
done(); // Don't forget to invoke done. It tell Jasmine we've finished
});
// Propagate promise resolution to 'then' functions using $apply().
$rootScope.$apply();
});
首先,将done
参数传递给您的测试,该参数用于异步测试。通过使用$q.defer()
,您可以控制何时resolve
Promise
。如果您需要测试承诺的结果,请将expect
放在.then
内。我已经添加了一个使用mockResponse
变量的示例,但只有在函数结尾的代码this.aPromise.promise.then(function (response) {...
中返回response
时,该变量才起作用。
此外,别忘了调用done
,它告诉Jasmine
我们已经完成了它。
最重要的是,最后调用$rootScope.$apply();
以便将承诺解析传播到.then
函数。
希望有帮助