11

摩卡网站指出:

“为了让事情变得更简单,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]

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

4

2 回答 2

22

这不是异步的。回调函数只是为了通知 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如果是这样,expect 通过以下方法(也称为)处理预期的错误throwError

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

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

// 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()回调。


更多附加说明:

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

现在,正如我上面提到的,node 中的一个常见习惯用法是异步函数不会抛出错误,而是将错误对象作为第一个参数传递。发生这种情况时,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 之类的库一起使用时有点多余,它允许您手动检查返回的错误对象,但是当您的断言库无法检查错误对象时(或者当您真的不检查时)它很有用关心异步函数的结果,但只想知道没有抛出错误)。

于 2013-10-13T00:33:00.690 回答
0

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

it('Test DNA', () => {
    return resolvedPromise.then( (result)=>{
       expect(result).to.equal('He is not a your father.');      
    },(err)=>{
       console.log(err);
    });
});
于 2017-01-17T07:05:13.553 回答