测试在摩卡预期故障(Test for expected failure in Mocha)

2019-07-19 21:39发布

采用摩卡,我试图测试是否构造函数抛出一个错误。 我一直没能这样用期待的语法做的,所以我想做到以下几点:

it('should throw exception when instantiated', function() {
  try {
    new ErrorThrowingObject();
    // Force the test to fail since error wasn't thrown
  }
  catch (error) {
   // Constructor threw Error, so test succeeded.
  }
}

这可能吗?

Answer 1:

您可以尝试使用柴氏 throw结构。 例如:

expect(Constructor).to.throw(Error);


Answer 2:

should.js

使用should.js与should.fail

var should = require('should')
it('should fail', function(done) {
  try {
      new ErrorThrowingObject();
      // Force the test to fail since error wasn't thrown
       should.fail('no error was thrown when it should have been')
  }
  catch (error) {
   // Constructor threw Error, so test succeeded.
   done();
  }
});

替代你可以使用应throwError

(function(){
  throw new Error('failed to baz');
}).should.throwError(/^fail.*/)

Chai

并与柴用掷 API

var expect = require('chai').expect
it('should fail', function(done) {
  function throwsWithNoArgs() {
     var args {} // optional arguments here
     new ErrorThrowingObject(args)
  }
  expect(throwsWithNoArgs).to.throw
  done()
});


Answer 3:

柴现在有

should.fail()expect.fail()

https://github.com/chaijs/chai/releases/tag/2.1.0



Answer 4:

2017年的答案,如果你需要使用异步代码来做到这一点 :使用的await 并且不需要任何其他库

it('Returns a correct error response when making a broken order', async function(){
  this.timeout(5 * 1000);
  var badOrder = {}
  try {
    var result = await foo.newOrder(badOrder)
    // The line will only be hit if no error is thrown above!
    throw new Error(`Expected an error and didn't get one!`)
  } catch(err) {
    var expected = `Missing required field`
    assert.equal(err.message, expected)
  }
});

注意,海报只是做同步的代码,但我希望有很多使用异步人对这个问题的标题在这里领导!



Answer 5:

摩卡在默认情况下是使用断言从Node.js的( https://nodejs.org/api/assert.html )。 你不需要任何外部库检查方法抛出一个错误。

断言有一个方法- assert.throws ,它有三个参数,但只有两个真正的问题在这里:

  • 功能-在这里传递函数,而不是函数调用
  • 错误 - 在这里通过或对象的构造或功能来检查错误

让我们想象一下,你有一个调用的函数sendMessage(message)时,未设置信息参数,它抛出一个错误。 功能代码:

function sendMessage(message) {
  if (!message || typeof message !== 'string') {
     throw new Error('Wrong message');
  }
  // rest of function
}

好了,为了测试它,你需要额外的功能,覆盖输入。 为什么? 由于assert.throws不给任何机会,参数传递到将要测试的功能。

因此,而不是

// WRONG
assert.throws(sendMessage, Error); // THIS IS WRONG! NO POSSIBILITY TO PASS ANYTHING

您需要创建匿名函数:

// CORRECT
assert.throws(() => {
  sendMessage(12);  // usage of wanted function with test parameters
}, Error)

你能看到区别么? 而是直接传递功能的,我已经把匿名函数里面的函数调用中,用事先准备好的输入调用它的目的。

那么关于第二个参数。 这要看从什么样的错误应该被抛出,在上面的例子中Error对象被抛出,所以我不得不把有Error 。 在这个动作的结果, assert.throws如果抛出的对象是同一类型的对象进行比较。 如果相反的Error不同的东西会被抛出,那么这部分需要改变。 例如,而不是Error ,我将抛出类型的值String

function sendMessage(message) {
  if (!message || typeof message !== 'string') {
     throw 'Wrong message'; // change to String
  }
  // rest of function
}

现在测试呼叫

assert.throws(() => {
  sendMessage(12); // usage of wanted function with test parameters
}, (err) => err === 'Wrong message')

相反的Error在第二个参数我用的比较功能,以抛出错误与预期进行比较。



Answer 6:

MarkJ的接受的答案是要走的道路和方式比其他人在这里简单。 让我告诉例子在现实世界中:

function fn(arg) {
  if (typeof arg !== 'string')
    throw TypeError('Must be an string')

  return { arg: arg }
}

describe('#fn', function () {
  it('empty arg throw error', function () {
    expect(function () {
      new fn()
    }).to.throw(TypeError)
  })

  it('non-string arg throw error', function () {
    expect(function () {
      new fn(2)
    }).to.throw(TypeError)
  })

  it('string arg return instance { arg: <arg> }', function () {
    expect(new fn('str').arg).to.be.equal('str')
  })
})


Answer 7:

如果你正在使用should.js你可以做(new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')

如果你不想应该独立的库,你也可以做这样的事情:

it('should do whatever', function(done) {
    try {
        ...
    } catch(error) {
        done();
    }
}

这样一来,你知道,如果在测试结束时所捕获的错误。 否则,你会得到一个超时错误。



Answer 8:

如果你不想一大堆源的包装到expect的参数,或者如果你有很多参数传递,它只是变得丑陋,你仍然可以做到这一点与原来的语法就好了通过利用done论据是提供(但最初忽略):

it('should throw exception when instantiated', function(done: Done) {
  try {
    new ErrorThrowingObject();
    done(new Error(`Force the test to fail since error wasn't thrown`));
  }
  catch (error) {
    // Constructor threw Error, so test succeeded.
    done();
  }
}

因为你使用done这里,它可以让你走在执行上面任意代码try ,然后指定正是在源你想记录故障。

通常情况下,有人可能想throwassert(false) ,但这些都将被捕获catch的的try ,并导致你做一些元检查,以确定是否抓住了误差为测试中的预期错误,或者如果它是最终确定你的测试失败。 这只是一个烂摊子。



Answer 9:

随着 throw (ES2016)

http://chaijs.com/api/bdd/#method_throw

为了清楚...这工作

it('Should fail if ...', done => {
    let ret = () => {
        MyModule.myFunction(myArg);
    };
    expect(ret).to.throw();
    done();
});

这不起作用

it('Should fail if ...', done => {
    let ret = MyModule.myFunction(myArg);
    expect(ret).to.throw();
    done();
});


文章来源: Test for expected failure in Mocha