有没有办法让 Chai 使用异步 Mocha 测试? [英] Is there a way to get Chai working with asynchronous Mocha tests?

查看:28
本文介绍了有没有办法让 Chai 使用异步 Mocha 测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Browser Runner 在 Mocha 中运行一些异步测试,并且我正在尝试使用 Chai 的期望样式断言:

I'm running some asynchronous tests in Mocha using the Browser Runner and I'm trying to use Chai's expect style assertions:

window.expect = chai.expect;
describe('my test', function() {
  it('should do something', function (done) {
    setTimeout(function () {
      expect(true).to.equal(false);
    }, 100);
  }
}

这不会给我正常的失败断言消息,而是我得到:

This doesn't give me the normal failed assertion message, instead I get:

Error: the string "Uncaught AssertionError: expected true to equal false" was thrown, throw an Error :)
    at Runner.fail (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3475:11)
    at Runner.uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3748:8)
    at uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3778:10)

所以它显然是在捕获错误,只是没有正确显示.任何想法如何做到这一点?我想我可以用一个错误对象调用完成",但随后我失去了像 Chai 这样的东西的所有优雅,它变得非常笨重......

So it's obviously catching the error, it's just not displaying it correctly. Any ideas how to do this? I guess I could just call "done" with an error object but then I lose all the elegance of something like Chai and it becomes very clunky...

推荐答案

您的异步测试在失败的 expect() 操作上生成异常,it()<无法捕获该异常/code> 因为异常是在 it() 的范围之外抛出的.

Your asynchronous test generates an exception, on failed expect()ations, that cannot be captured by it() because the exception is thrown outside of it()'s scope.

您看到的捕获异常是使用节点下的 process.on('uncaughtException') 或在浏览器中使用 window.onerror() 捕获的.

The captured exception that you see displayed is captured using process.on('uncaughtException') under node or using window.onerror() in the browser.

要解决这个问题,您需要在setTimeout()调用的异步函数中捕获异常,以便首先调用done()范围.您还需要不带参数调用 done() 来表示成功,否则 mocha 会报告超时错误,因为您的测试函数永远不会发出已完成的信号:

To fix this issue, you need to capture the exception within the asynchronous function called by setTimeout() in order to call done() with the exception as the first parameter. You also need to call done() with no parameter to indicate success, otherwise mocha would report a timeout error because your test function would never have signaled that it was done:

window.expect = chai.expect;

describe( 'my test', function() {
  it( 'should do something', function ( done ) {
    // done() is provided by it() to indicate asynchronous completion
    // call done() with no parameter to indicate that it() is done() and successful
    // or with an error to indicate that it() failed
    setTimeout( function () {
      // Called from the event loop, not it()
      // So only the event loop could capture uncaught exceptions from here
      try {
        expect( true ).to.equal( false );
        done(); // success: call done with no parameter to indicate that it() is done()
      } catch( e ) {
        done( e ); // failure: call done with an error Object to indicate that it() failed
      }
    }, 100 );
    // returns immediately after setting timeout
    // so it() can no longer catch exception happening asynchronously
  }
}

在您的所有测试用例上这样做很烦人,而不是 DRY,因此您可能希望提供一个函数来为您执行此操作.让我们调用这个函数 check():

Doing so on all your test cases is annoying and not DRY so you might want to provide a function to do this for you. Let's call this function check():

function check( done, f ) {
  try {
    f();
    done();
  } catch( e ) {
    done( e );
  }
}

使用 check(),您现在可以按如下方式重写异步测试:

With check() you can now rewrite your asynchronous tests as follows:

window.expect = chai.expect;

describe( 'my test', function() {
  it( 'should do something', function( done ) {
    setTimeout( function () {
      check( done, function() {
        expect( true ).to.equal( false );
      } );
    }, 100 );
  }
}

这篇关于有没有办法让 Chai 使用异步 Mocha 测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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