21

エラーが有効な場合はスローされ、そうでない場合は何もスローされないという方法でエラーを処理する関数のテキストを実行しようとしています。問題は、使用中にパラメータを設定できないように見えることです:

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

理想的には、次を使用することです。

expect(handleError(validError)).to.throw(Error);

この機能を実現する方法はありますか?

関数のコード:

function handleError (err) {
    if (err !== true) {
        switch (err) {
            case xxx:
            ...
        }
        throw "stop js execution";
    else {}
}

テストのコード (意図したとおりに動作しない):

it("should stop Javascript execution if the parameter isnt \"true\"", function() {
    expect(handleError).to.be.a("function");
    expect(handleError(true)).to.not.throw(Error);
    expect(handleError("anything else")).to.throw(Error);
});
4

4 に答える 4

43

問題は、handleError を呼び出してから、期待どおりの結果を渡していることです。handleError がスローされた場合、呼び出されることはありません。

関数が呼び出されたときに何が起こるかをexpectが確認できるように、expectが呼び出されるまでhandleErrorの呼び出しを延期する必要があります。幸いなことに、これは期待が望んでいるものです:

expect(function () { handleError(true); }).to.not.throw();
expect(function () { handleError("anything else") }).to.throw("stop js execution");

throw のドキュメントを読むと、関連付けられた Expect に関数を渡す必要があることがわかります。

于 2013-10-03T02:58:06.383 に答える
7

私は今日この同じ問題に遭遇し、ここに記載されていない別の解決策を選択しました: を使用した部分関数アプリケーションbind():

expect(handleError.bind(null, true)).to.not.throw();
expect(handleError.bind(null, "anything else")).to.throw("stop js execution");

これには、単純な古い JavaScript を使用して簡潔であるという利点があり、追加の関数を必要とせずthis、関数がそれに依存する場合に の値を提供することさえできます。

于 2016-04-24T16:47:16.077 に答える
1

David Norman が推奨するように、Lambda で関数呼び出しをラップすることは、この問題を解決する 1 つの良い方法です。

ただし、より読みやすいソリューションを探している場合は、これをテスト ユーティリティに追加することもできます。この関数は、メソッドを使用して関数をオブジェクトにラップします。withArgsこれにより、同じステートメントをより読みやすい方法で記述できます。理想的には、これは Chai に組み込まれます。

var calling = function(func) {
  return {
    withArgs: function(/* arg1, arg2, ... */) {
      var args = Array.prototype.slice.call(arguments);
      return function() {
        func.apply(null, args);
      };
    }
  };
};

次に、次のように使用します。

expect(calling(handleError).withArgs(true)).to.not.throw();        
expect(calling(handleError).withArgs("anything else")).to.throw("stop js execution");

英語のように読めます!

于 2016-01-04T11:35:25.613 に答える
0

私はES2015をbabel stage-2プリセットで使っていますが、そうするならこちらも使えます。

@StephenM347 ソリューションを使用し、それを少し変更して、さらに読みやすい IMHO に短くしました。

let expectCalling = func => ({ withArgs: (...args) => expect(() => func(...args)) });

使用法 :

expectCalling(handleError).withArgs(true).to.not.throw();        
expectCalling(handleError).withArgs("anything else").to.throw("stop js execution");

注:同じ使用法を希望する場合(そしてそのまま使用することに固執する場合expect()):

    let calling = func => ({ withArgs: (...args) => () => func(...args) });
于 2016-01-24T19:26:32.720 に答える