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

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

问题描述

我正在使用浏览器运行器在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() ations, it()无法捕获,因为异常抛出 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
  }
}

这样做l您的测试用例很烦人而且不干燥,所以您可能希望提供一个功能来为您执行此操作。让我们调用这个函数 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天全站免登陆