茉莉花等待私有函数,使异步调用来解决诺言

时间:2019-06-11 13:10:22

标签: javascript angularjs promise async-await jasmine

我有一个函数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()之前等待承诺解决?

1 个答案:

答案 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函数。

希望有帮助