与茉莉花中 ES6 承诺的 then/catch 方法同步

Synchronize with then/catch method of ES6 Promises in Jasmine

本文关键字:catch 方法 同步 then 茉莉花 ES6 承诺      更新时间:2023-09-26

我有一个角度控制器需要测试。此控制器调用服务以从服务器检索数据。该服务返回 ES6 承诺。

function MyController($scope, MyService) {
  $scope.doSomething = function () {
    MyService.foo().then() {
      whatever...;
    };
  };
};

在我的茉莉花测试中,我也嘲笑了返回承诺的服务:

var resolve;
var reject;
createPromise = function () {
 return new Promise(function (_resolve, _reject) {
    resolve = _resolve;
    reject = _reject;
  });
};
var myServiceMock = {
  doSomething: jasmine.createSpy('doSomething').and.callFake(createPromise)    
};
beforeEach(module('someApp', function ($provide) {
  $provide.value('MyService', myServiceMock);
}));

我手动调用全局解析(或拒绝),无论是否带有参数来检查我的控制器。

it('shall call the service', function () {
  $scope = $rootScope.$new();
  controller = $controller('MyService', { $scope: $scope });
  controller.doSomething();
  myService.resolve();
  expect(whatever...);
});

问题是解析调用是异步的。所以我正在测试我的预期结果,同时运行 then 函数。

我没有返回 Promises,而是尝试返回简单的自定义对象,该对象会将 resolve 转换为同步调用,但事实证明 Promise 有一些特定的规则,这些规则太麻烦了,无法在模拟中重新实现(例如当你有 then.()。例如 catch().then 模式)。

有没有办法在茉莉花中以简单而同步的方式测试这种东西?

你需要告诉 Jasmine 你的测试是异步的,它应该等待它完成,然后再决定它失败了。为此,您可以在规范声明中添加一个 done 参数(it调用),并在期望结束时调用done

it('shall call the service', function (done) {
  $scope = $rootScope.$new();
  controller = $controller('MyService', { $scope: $scope });
  var promise = 
    controller.doSomething()
      .then(function() {
         expect(whatever...);
         done();
      });
  myService.resolve();
});

使模拟自动解析的一种更简单方法是使用 Promise.resolve 方法:

doSomething: jasmine.createSpy('doSomething').and.returnValue(Promise.resolve())

然后,您无需调用myService.resolve - 模拟会自动返回已解决的承诺。

我最近开始使用 jasmine-promise 模块,它使编写 promise 调用变得更加容易 - 并确保如果 promise 被拒绝,则会报告错误和调用堆栈,以便于调试。有了jasmine-promises,这将变成:

it('shall call the service', function () {
  $scope = $rootScope.$new();
  controller = $controller('MyService', { $scope: $scope });
  return controller.doSomething()
      .then(function() {
         expect(whatever...);
      });
});