首页 > 解决方案 > 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: Cannot read property 'then' of undefined。我将其追溯到以下行:this.aPromise.promise.then(function (response) {

我正在尝试测试...代码行。我如何确保 Jasmine 在运行我的之前等待承诺解决expect()

标签: javascriptangularjspromiseasync-awaitjasmine

解决方案


您应该尝试使用$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();在最后调用以将 Promise 解析传播到.then函数。

希望能帮助到你


推荐阅读