当使用 Chai as Promised 时,我真的需要在测试中返回一个承诺吗? [英] Do I really need to return a promise in test when using Chai as Promised?

查看:27
本文介绍了当使用 Chai as Promised 时,我真的需要在测试中返回一个承诺吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Chai as Promised 文档声明如下:

<块引用>

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

网站上的例子如下:

<块引用>

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

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

it('应该解析用户', function () {$state.get(state).resolve.user(dataservice, {用户 ID:testUser.id}).should.eventually.eq(testUser);$rootScope.$apply();});

而且它工作得很好.我确定它确实如此,因为我将 testUser 更改为其他测试失败的内容.就像我预期的那样.所以我不确定我在这里做错了什么.

事实上,当我修改代码以返回承诺时,它失败并显示错误错误:超过 2000 毫秒超时.确保在此测试中调用了 done() 回调."修改后的代码如下:

it('应该解析用户', function () {var promise = $state.get(state).resolve.user(dataservice, {用户 ID:testUser.id}).should.eventually.eq(testUser);$rootScope.$apply();回报承诺;});

这里有点混乱.它可能与 Angular $q 有关.为了清楚起见,函数 resolve.user 返回一个 $q 承诺.

解决方案

在上面的例子中,Mocha 链在 $rootScope.$apply() 被调用后返回了 promise,所以链式 then 需要另一个 $rootScope.$apply() 来执行.没有这个,承诺链的其余部分不会执行并导致超时.

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

如图所示此处, chai-as-promised 可以修改为支持 $q 承诺并自动应用 $rootScope.$apply() 到断言的承诺:

chaiAsPromised.transferPromiseness = function (assertion, promise) {assertion.then = promise.then.bind(promise);if (!('$$state' in promise))返回;注入(函数($rootScope){如果 (!$rootScope.$$phase)$rootScope.$digest();});};

Chai as Promised documentation states as follows:

Notice: either return or notify(done) must be used with promise assertions.

And the examples on the site are as follows:

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

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

The thing is; I actually wrote a test using chai as promised without returning the promise. Like so:

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

And it works perfectly fine. I am sure it does as I change testUser to something else the test fails. Just like I expected. So I am not sure if I am doing something wrong here.

In fact, when I modified the code to return a promise, it failed with error "Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test." The modified code is below:

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

A little confused here. It might have something to do with Angular $q. To make it clear, the function resolve.user returns a $q promise.

解决方案

In the case above Mocha chains returned promise after $rootScope.$apply() was called, so chained then needs another $rootScope.$apply() to be executed. Without this the rest of promise chain is not executed and results in timeout.

Returning promises in Mocha specs is intended for asynchronous specs, this is necessary for testing non-Angular promises. $q promises are synchronous and tied to Angular digests.

As shown here, chai-as-promised can be modified to support $q promises and apply $rootScope.$apply() automatically to asserted promises:

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

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

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

这篇关于当使用 Chai as Promised 时,我真的需要在测试中返回一个承诺吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆