7

我正在尝试通过业力单元测试chai-as-promised来处理$q承诺。

  svc.test = function(foo){
    if (!foo){
      // return Promise.reject(new Error('foo is required'));
      return $q.reject(new Error('foo is required'));
    } else {
      // get data via ajax here
      return $q.resolve({});
    }
  };


  it.only('should error on no foo', function(){
    var resolvedValue = MyServices.test();
    $rootScope.$apply();
    return resolvedValue.should.eventually.be.rejectedWith(TypeError, 'foo is required');
  });

单元测试只是超时。我不确定我在这里做错了什么才能得到正确解决的承诺。使用似乎是一个问题$q——当我使用本机时Promise.reject()它工作正常。

我在这里提交了一张票,但似乎没有人回应: https ://github.com/domenic/chai-as-promised/issues/150

4

2 回答 2

2

chai-as-promised期望修改 promise 断言的方式是transferPromisenessmethod

默认情况下,Chai 作为 Promised 的断言返回的 Promise 是常规的 Chai 断言对象,使用从输入 Promise 派生的单个 then 方法进行扩展。要改变这种行为,例如输出一个带有更多有用的糖方法的承诺,例如在大多数承诺库中找到的,你可以覆盖 chaiAsPromised.transferPromiseness。

对于 Angular 1.3+ 的支持,$qpromise 可以通过$$state属性进行鸭式类型,因此本机 Promise 不会受到影响:

chaiAsPromised.transferPromiseness = function (assertion, promise) {
  assertion.then = promise.then.bind(promise);

  if (!('$$state' in promise))
    return;

  inject(function ($rootScope) {
    if (!$rootScope.$$phase)
      $rootScope.$digest();
  });
};

chaiAsPromised用 . 链接每个断言的承诺then。即使承诺已解决,链的其余部分仍然需要手动触发摘要$rootScope.$digest()

只要规范不包含异步代码,它就会变成同步的,不需要返回任何承诺:

it('...', () => {
  ...
  expect(...).to.eventually...;
  expect(...).to.eventually...;
});

$rootScope.$digest()并且在每组eventually断言/期望transferPromiseness未设置时等于强制:

it('...', () => {
  ...
  expect(...).to.eventually...;
  expect(...).to.eventually...;
  $rootScope.$digest();
});
于 2016-05-22T11:57:11.993 回答
1
于 2016-07-06T09:35:39.953 回答