javascript カバレッジ jasmine でエラーが発生すると予想されるテストを書くには?



javascript カバレッジ eclipse (7)

私は、エラーが予想されるJasmine Test Frameworkのテストを作成しようとしています。 現時点では、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()や他のいくつかの変種も試してみましたが、それを動作させる方法を理解できません。


Answer #1

あなたは関数をexpect(...)呼び出しに渡す必要があります。 ここにあるコード:

// incorrect:
expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));

結果をexpect(...)に渡すためにparser.parse(raw)を実際に呼び出そうとしていexpect(...)

代わりに無名関数を使ってみてください:

expect( function(){ parser.parse(raw); } ).toThrow(new Error("Parsing is not possible"));

Answer #2

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://.com/a/13233194/1248889も参照してくださいhttps://.com/a/13233194/1248889


Answer #3

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

Answer #4

前述のように、テストで説明している関数であるため、関数をtoThrowに渡す必要があります。「この関数がxをスローすると期待しています」

expect(() => parser.parse(raw))
  .toThrow(new Error('Parsing is not possible'));

Jasmine-Matchersを使用している場合は、状況に応じて次のいずれかを使用することもできます。

// 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);

Answer #5

使用しているのは:

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) {

おそらく、このように書くべきでしょう(ラムダ - 無名関数を使って):

expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");

これは、次の例で確認されています。

expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");

Douglas Crockfordは、「throw new Error()」(プロトタイプ作成)を使用する代わりに、このアプローチを強く推奨します。

throw {
   name: "Error",
   message: "Parsing is not possible"
}

Answer #6

coffeescript愛好家のために

expect( => someMethodCall(arg1, arg2)).toThrow()

Answer #7

まだこの問題に直面している可能性のある人にとっては、私にとってはポストされた解決策はうまくいかず、このエラーをスローし続けました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');
                });
            }));




jasmine