ジャスミンでエラーがスローされると予想されるテストを書く方法は?
-
30-09-2019 - |
質問
テストを書き込もうとしています ジャスミンテストフレームワーク エラーが予想されます。現在、私はaを使用しています GithubからのJasmine node.js統合.
私のノードモジュールには、次のコードがあります。
throw new Error("Parsing is not possible");
今、私はこのエラーを期待するテストを書き込もうとしています:
describe('my suite...', function() {
[..]
it('should not parse foo', function() {
[..]
expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
});
});
私も試しました Error()
そして、他のいくつかのバリエーションであり、それを機能させる方法を理解することはできません。
解決
関数をに渡す必要があります expect(...)
電話。ここにあるコード:
// incorrect:
expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
実際にしようとしています 電話 parser.parse(raw)
結果を渡そうとして expect(...)
,
代わりに匿名関数を使用してみてください:
expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));
他のヒント
あなたは使用しています:
expect(fn).toThrow(e)
ただし、関数コメントをご覧になると(予想は文字列です):
294 /**
295 * Matcher that checks that the expected exception was thrown by the actual.
296 *
297 * @param {String} expected
298 */
299 jasmine.Matchers.prototype.toThrow = function(expected) {
おそらくこのように書くべきだと思います(Lambdaを使用 - 匿名関数を使用):
expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");
これは、次の例で確認されています。
expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");
ダグラス・クロックフォードは、「新しいエラー()」(プロトタイピングウェイ)を使用する代わりに、このアプローチを強くお勧めします。
throw {
name: "Error",
message: "Parsing is not possible"
}
JasmineのTothrow Matcherを次のものに置き換えます。これにより、例外の名前のプロパティまたはそのメッセージプロパティを一致させることができます。私にとって、これにより、テストが簡単に書くことができ、脆くなります。
throw {
name: "NoActionProvided",
message: "Please specify an 'action' property when configuring the action map."
}
そして、次のようにテストします。
expect (function () {
.. do something
}).toThrow ("NoActionProvided");
これにより、テストを破ることなく、後で例外メッセージを調整できます。重要なことは、予想されるタイプの例外を投げたということです。
これは、これを可能にするTothrowの代替品です。
jasmine.Matchers.prototype.toThrow = function(expected) {
var result = false;
var exception;
if (typeof this.actual != 'function') {
throw new Error('Actual is not a function');
}
try {
this.actual();
} catch (e) {
exception = e;
}
if (exception) {
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected) || this.env.equals_(exception.name, expected));
}
var not = this.isNot ? "not " : "";
this.message = function() {
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function " + not + "to throw", expected ? expected.name || expected.message || expected : " an exception", ", but it threw", exception.name || exception.message || exception].join(' ');
} else {
return "Expected function to throw an exception.";
}
};
return result;
};
唯一の目的が別のものをラップすることを目的とする匿名関数を作成するよりもエレガントなソリューションは、ES5を使用することです bind
働き。バインド関数は、呼び出された場合、その新しい関数を作成します this
キーワードは、新しい関数が呼び出されたときに提供されたすべてのものに先行する一連の引数を持つ、提供された値に設定されています。
それ以外の:
expect(function () { parser.parse(raw, config); } ).toThrow("Parsing is not possible");
検討:
expect(parser.parse.bind(parser, raw, config)).toThrow("Parsing is not possible");
バインド構文を使用すると、異なる機能で関数をテストできます this
価値、そして私の意見では、テストをより読みやすくします。参照: https://stackoverflow.com/a/13233194/1248889
前述のように、関数をに渡す必要があります toThrow
テストで説明している関数なので、「この関数がxを投げると思います」
expect(() => parser.parse(raw))
.toThrow(new Error('Parsing is not possible'));
使用する場合 ジャスミンマッチャー また、状況に合った場合、次のいずれかを使用することもできます。
// I just want to know that an error was
// thrown and nothing more about it
expect(() => parser.parse(raw))
.toThrowAnyError();
また
// I just want to know that an error of
// a given type was thrown and nothing more
expect(() => parser.parse(raw))
.toThrowErrorOfType(TypeError);
私はそれがもっとコードであることを知っていますが、あなたもできます:
try
do something
@fail Error("should send a Exception")
catch e
expect(e.name).toBe "BLA_ERROR"
expect(e.message).toBe 'Message'
coffeescript愛好家のために
expect( => someMethodCall(arg1, arg2)).toThrow()
まだこの問題に直面している可能性がある人にとっては、投稿されたソリューションは機能せず、このエラーを投げ続けました。 Error: Expected function to throw an exception.
後で、エラーを投げると予想していた関数は非同期関数であり、約束が拒否されてエラーを投げることを期待していたことに気付きました。それが私のコードで行っていたことです。
throw new Error('REQUEST ID NOT FOUND');
そして、それは私が私のテストでしたことであり、それはうまくいきました:
it('Test should throw error if request not found', willResolve(() => {
const promise = service.getRequestStatus('request-id');
return expectToReject(promise).then((err) => {
expect(err.message).toEqual('REQUEST NOT FOUND');
});
}));