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.
}
}
これは可能ですか?
Chai'sthrow
構文を使用してみてください。例えば:
expect(Constructor).to.throw(Error);
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();
}
});
代わりに、shouldを使用できます throwError
(function(){
throw new Error('failed to baz');
}).should.throwError(/^fail.*/)
そして、チャイで throw 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()
});
非同期コードでこれを行う必要がある場合は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)
}
});
ポスターは同期コードのみを実行していることに注意してください。ただし、非同期を使用している多くの人々が質問のタイトルによってここに導かれたと思います!
デフォルトのMochaは、node.jsからAssertを使用しています( https://nodejs.org/api/assert.html ) 。メソッドがエラーをスローするかどうかを確認するために外部ライブラリは必要ありません。
アサートにはメソッドがあります-_assert.throws
_、3つのパラメーターがありますが、ここで重要なのは2つだけです。
メッセージパラメータが設定されていないときにエラーをスローするsendMessage(message)
という関数があるとします。機能コード:
_function sendMessage(message) {
if (!message || typeof message !== 'string') {
throw new Error('Wrong message');
}
// rest of function
}
_
OK、それをテストするためには、入力をカバーする追加の関数が必要です。どうして? _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
の代わりに、スローされたエラーと期待値を比較するために比較関数を使用しました。
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')
})
})
たくさんのソースを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)
に誘惑される可能性がありますが、これらは両方ともcatch
のtry
に捕捉され、あなたにそうさせますキャッチしたエラーがテストで予想されるエラーであったか、それともテストが失敗したという最終決定であるかを判断するためのメタチェック。それはただの混乱です。
should.js を使用している場合は、(new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')
別のライブラリを使用したくない場合は、次のようにすることもできます。
it('should do whatever', function(done) {
try {
...
} catch(error) {
done();
}
}
このようにして、テストが終了した場合にエラーがキャッチされたことがわかります。そうしないと、タイムアウトエラーが発生します。
ありChaithrow
(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();
});