使用Chai作为承诺时,我是否真的需要在测试中返回一个承诺?

时间:2016-06-22 17:28:26

标签: javascript angularjs angular-promise chai chai-as-promised

Chai as Promised documentation声明如下:

  

注意:return或notify(done)必须与promise断言一起使用。

网站上的示例如下:

return doSomethingAsync().should.eventually.equal("foo");

doSomethingAsync().should.eventually.equal("foo").notify(done);

事情是;我实际上是按照承诺使用chai编写了一个测试而没有返回承诺。像这样:

it('should resolve user', function () {
    $state.get(state).resolve.user(dataservice, {
      userId: testUser.id
    }).should.eventually.eq(testUser);
    $rootScope.$apply();
  });

它完美无缺。我确信它会将testUser更改为其他测试失败的内容。就像我预期的那样。所以我不确定我在这里做错了什么。

事实上,当我修改代码以返回一个promise时,它失败并显示错误“Error:超过2000ms的超时。确保在此测试中调用done()回调。”修改后的代码如下:

it('should resolve user', function () {
    var promise = $state.get(state).resolve.user(dataservice, {
      userId: testUser.id
    }).should.eventually.eq(testUser);
    $rootScope.$apply();
    return promise;
  });

这里有点困惑。它可能与Angular $ q有关。为清楚起见,函数resolve.user返回$ q promise。

1 个答案:

答案 0 :(得分:2)

在上述情况下,Mocha链在调用$rootScope.$apply()后返回了promise,因此链式then需要执行另一个$rootScope.$apply()。如果没有这个,其余的promise链就不会被执行并导致超时。

Mocha规范中的返回承诺适用于异步规范,这对于测试非Angular承诺是必要的。 $q承诺是同步的并且与Angular摘要相关联。

如图所示here,可以修改chai-as-promised以支持$q承诺,并自动将$rootScope.$apply()应用于声明的承诺:

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

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

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