3

いくつかの MSpec BDD テストを書いているときに、失敗すると予想していたテストが成功するというシナリオに出くわしましたが、それはすべてのテストを実行したときだけでした。テストを単独で実行すると、期待どおりに失敗しました。調査の結果、前のテストで設定された状態が、2 番目のテストが実行される前にリセットされていないことがわかりました。これにより、2 番目のテストが失敗すると予想していたときに、2 番目のテストが成功しました。次の考案されたコードは、シナリオを再現します。

public class ContextBase
{
    protected static object state;
}

public class Context_a : ContextBase
{
    Establish context = () => { state = new object(); };

    It should_set_state = () => state.ShouldNotBeNull();
}

public class Context_b : ContextBase
{
    Establish context = () => {  };

    It should_set_state = () => state.ShouldNotBeNull();
}

Context_a が Context_b の前に実行され、Context_B が実行された時点で Context_A に設定された状態がまだ設定されているため、これらのテストは両方ともパスします。Context_B を単独で実行すると、状態が設定されていないため、テストは失敗します。興味深いことに、Context_B から空の Establish ステートメントを削除すると、Context_B は常に期待どおりに失敗します。

私は MSpec に比較的慣れていないので、この動作には驚きました。このような状態は、各コンテキストを実行する間にリセットされると想定しました。おそらく私は何かを見逃しています...これらのテストを正しく構築していますか? MSpec がコンテキスト間でこのような状態を自動的にリセットしない場合、私の例のような場合に状態が確実にリセットされるようにするには、どのような戦略を使用する必要がありますか? すべての状態フィールドを null に設定する ContextBase クラスに、確立ラムダを配置する必要がありますか?

4

1 に答える 1

2

MSpec は、実行中のコンテキスト間で静的状態を「リセット」しません。これは、通常の静的変数から知っている動作に従います。つまり、手動で行わない限り、アプリケーション (つまりテスト実行) の実行中は再初期化されません。Establish各コンテキストのすべてのフィールドを初期化することをお勧めします。

もう 1 つのオプションはEstablish、基本クラスにエクストラを配置することですが、これにより重要な情報がコンテキストから隠されます。フィールドが特定の値で初期化されたことを確認するには、基本クラスに移動する必要があります。protected staticしかし、DRY は一般的なテストには適用されません。私は、派生コンテキストから呼び出すメソッドを持つ基本クラスを使用することを好みます(例については、この回答を参照してください)。

于 2013-02-14T08:46:00.850 に答える