如何使用expect.js传递测试async done()出错?

时间:2013-10-12 20:45:17

标签: javascript

摩卡网站声明:

“为了使事情更容易,done()回调接受错误,所以我们可以直接使用它:[见他们的例子]”

让我们尝试一下:

it('works',function(done){
  expect(1).to.be(1)
  done( new Error('expected error') )
})
/* Insert the error manually for testing and clarity. */

运行它并:

1 failing

1) works:
 Error: expected error
  at Context.<anonymous>
  [stack trace]

当错误响应是期望的结果时,我们如何使测试通过?

2 个答案:

答案 0 :(得分:21)

那不是异步。回调函数只是为了通知mocha您正在测试异步代码,因此在调用回调函数之前,mocha不应运行下一个测试。这是如何使用回调函数的示例:

it('works',function(done){
    setTimeout(function(){
        // happens 0.5 seconds later:
        expect(1).to.be(1);
        done(); // this tells mocha to run the next test
    },500);
});

此外,mocha不处理任何形式的异常,异步或其他。它会将其留给您选择的异常库。在你的情况下,你正在使用expect.js?如果是这样,期望通过throwException方法(也称为throwError)来处理预期的错误:

it('throws an error',function(done){
    expect(function(){
        throw new Error('expected error');
    }).to.throwError(/expected error/);
});

现在,一般来说,node.js中的异步代码不会抛出错误。它们将错误作为参数传递给回调。因此,要处理异步错误,您只需检查错误对象:

// using readFile as an example of async code to be tested:
it('returns an error',function(done){
    fs.readFile(filename, function (err, data) {
        expect(err).to.be.an(Error);
        done(); // tell mocha to run next test
    })
});

如果您正在检查同步错误,请使用to.throwError();如果您正在检查异步错误,请使用to.be.an(Error)


附加说明:

我第一次看到这个时我很难过。 mocha如何知道测试是同步还是异步,当唯一的区别是天气,你传递给它的函数是否接受参数?如果你像我一样,并且在想知道如何,我了解到javascript中的所有函数都有一个length属性,它描述了它在声明中接受了多少个参数。不,不是arguments.length,而是函数自己的length。例如:

function howManyArguments (fn) {
    console.log(fn.length);
}

function a () {}
function b (x) {}
function c (x,y,z) {}

howManyArguments(a); // logs 0
howManyArguments(b); // logs 1
howManyArguments(c); // logs 3
howManyArguments(howManyArguments); // logs 1
howManyArguments(function(x,y){}); // logs 2

因此,mocha基本上检查函数的长度,以确定将其视为同步函数或异步函数的天气,并暂停执行等待done()回调,如果它是异步的。


更多附加说明:

像大多数其他js单元测试运行器和库一样,Mocha通过捕获错误来工作。因此,如果断言失败,它期望像expect(foo).to.be.an.integer()这样的函数抛出错误。这就是mocha如何与expect或chai等断言库进行通信。

现在,正如我上面提到的,节点中常见的习惯用法是异步函数不会抛出错误,而是将错误对象作为第一个参数传递。当发生这种情况时,mocha无法检测到错误,因此无法检测到失败的测试。解决这个问题的方法是,如果将错误对象从异步代码传递给回调函数,它将把它视为抛出错误。

所以,参考上面的一个例子:

it('executes without errors',function(done){
    fs.readFile(filename, function (err, data) {
        done(err); // if err is undefined or null mocha will treat
                   // it as a pass but if err is an error object
                   // mocha treats it as a fail.
    })
});

或者简单地说:

it('executes without errors',function(done){
    fs.readFile(filename,done);
});    

严格地说,当与expect.js这样的库一起使用时,这个功能有点多余,它允许你手动检查返回的错误对象,但是当你的断言库无法检查错误对象时(或者当你没有非常关心异步函数的结果,但只想知道没有抛出错误。

答案 1 :(得分:0)

您还可以返回您的异步,例如承诺,如下所示。

it('Test DNA', () => {
    return resolvedPromise.then( (result)=>{
       expect(result).to.equal('He is not a your father.');      
    },(err)=>{
       console.log(err);
    });
});