20

Mochaを使用して、コンストラクターがエラーをスローするかどうかをテストしようとしています。私はexpect構文を使用してこれを行うことができなかったので、次のことを行いたいと思います。

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.
  }
}

これは可能ですか?

4

9 に答える 9

30

should.js

should.failでshould.jsライブラリを使用する

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();
  }
});

別の方法として、 shouldthrowErrorを使用できます

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

チャイ

そして、throwapiを使用しチャイ

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()
});
于 2013-02-15T08:43:04.873 に答える
14

チャイの throwコンストラクトを使ってみることができます。例えば:

expect(Constructor).to.throw(Error);
于 2013-02-14T16:45:40.463 に答える
13

チャイは今持っています

should.fail()expect.fail()

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

于 2015-03-22T19:28:45.333 に答える
12

非同期コードでこれを行う必要がある場合は、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)
  }
});

ポスターは同期コードのみを実行していたことに注意してください。ただし、非同期を使用している多くの人々がここで質問のタイトルに導かれていると思います。

于 2017-07-06T11:30:27.393 に答える
9

Mochaは、デフォルトでnode.js(https://nodejs.org/api/assert.html )のAssertを使用しています。メソッドがエラーをスローするかどうかをチェックするために外部ライブラリは必要ありません。

Assertにはメソッドがあります- assert.throws、3つのパラメーターがありますが、ここで実際に重要なのは2つだけです。

  • 関数-ここでは関数呼び出しではなく関数を渡します
  • エラー-ここでは、エラーをチェックするためのパスまたはオブジェクトのコンストラクターまたは関数

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)

違いがわかりますか?関数を直接渡す代わりに、準備された入力で呼び出すことを目的として、匿名関数内に関数呼び出しを配置し​​ました。

2番目のパラメーターはどうですか。スローするエラーの種類によって異なりますが、上記の例で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')

2番目のパラメーターの代わりにError、スローされたエラーを期待値と比較するために比較関数を使用しました。

于 2017-10-23T12:18:17.703 に答える
4

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')
  })
})
于 2018-03-13T20:35:33.647 に答える
3

大量のソースをパラメーターにラップしたくない場合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し、ソース内のどこで失敗を記録するかを正確に指定できます。

通常、誰かがthrowまたはassert(false)に誘惑される可能性がありますが、これらは両方とものによってキャッチされ、キャッチしcatchtryエラーがテストからの予期されたエラーであるか、それとも最終的なエラーであるかを判断するためにメタチェックを実行します。テストが失敗したという判断。それはただの混乱です。

于 2018-12-14T19:53:56.010 に答える
2

should.jsを使用している場合は、次のことができます(new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')

別のライブラリを作成したくない場合は、次のようにすることもできます。

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

このようにして、テストが終了した場合にエラーがキャッチされたことがわかります。そうしないと、タイムアウトエラーが発生します。

于 2013-02-14T16:53:25.023 に答える
0

チャイ 付き( ES2016 throw

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();
});
于 2017-11-04T13:00:54.047 に答える