0

長い投稿でごめんなさい...

ブラウンフィールドプロジェクトに紹介されている間、私は特定のユニットテストのセットと何を考えるべきかについて疑問を持っています。ストアドプロシージャをラップするrepostoryクラスがあり、開発者ガイドブックに、このクラスをどのように構成するかを説明する特定のガイドライン(ルール)があるとします。クラスは次のようになります。

public class PersonRepository
{
public PersonCollection FindPersonsByNameAndCity(string personName, string cityName)
{
    using (new SomeProfiler("someKey"))
    {
        var sp = Ioc.Resolve<IPersonStoredProcedure>();

        sp.addNameArguement(personName);
        sp.addCityArguement(cityName);

        return sp.invoke();
    }
} }

ここで、もちろん、いくつかの統合テストを作成し、SPを呼び出すことができ、動作が期待どおりであることをテストします。ただし、次のことを主張する単体テストを作成しますか。

  • 入力パラメーター「someKey」を持つSomeProfilerのコンストラクターが呼び出されます
  • PersonStoredProcedureのコンストラクターはと呼ばれます
  • ストアドプロシージャのaddNameArgumentメソッドは、パラメータpersonNameを使用して呼び出されます。
  • ストアドプロシージャのaddCityArgumentメソッドは、パラメータcityNameを使用して呼び出されます。
  • ストアドプロシージャでinvokeメソッドが呼び出されます-

もしそうなら、私は潜在的に、振る舞いに加えて、メソッドの構造全体をテストするでしょう。私の最初の考えは、それはやり過ぎだということです。ただし、チームによって実施されたコーディングプラクティスに関して、これらのテストは、均一で「正しい」構造を確認し、次のレイヤーが正しく呼び出されることを確認します(DALからDB、BLLからDALなど)。

私の場合、これらのタイプのテストは、アプリケーションの各レイヤーに対して実行されます。

フォローアップの質問-SomeProfilerクラスの使用は私には慣習のような匂いがします-これに対する明示的なテストを作成する代わりに、静的コード分析またはユニットテスト+リフレクションを使用して慣習スタイルのテストを作成できますか?

前もって感謝します。

4

2 に答える 2

0

あなたの最初の考えは正しかったと思います-これはやり過ぎです。リフレクションを使用して、クラスに期待するメソッドがあることを確認できますが、その方法でテストするかどうかはわかりません。

おそらく、単体テストの代わりに、FxCop / StyleCopやnDependなどのツールを使用して、特定のアセンブリ/dll内のすべてのクラスにこれらのプロパティがあることを確認する必要があります。

私は「必要なものだけをコーディングする」ことを信じていると言っても、メソッドが存在することをテストする理由は、コードのどこかで使用し、特定のケースをテストできるか、テストできないかのどちらかです。無関係です。

于 2011-06-22T13:53:52.003 に答える
0

単体テストは、実装ではなく、動作に焦点を当てる必要があります。したがって、特定の引数が設定または渡されていることを確認するためのテストを作成しても、テスト戦略に大きな価値はありません。

提供されている例はデータベースと通信しているように見えるため、環境の可用性、データベーススキーマ、既存のデータなど、追加のセットアップと前提条件を持つ物理的な依存関係と通信する必要があるため、実際には「単体テスト」とは見なされません。 、ストアドプロシージャなど。作成するテストは、実際にはこれらの前提条件も検証しています。

現在の状態では、これらのタイプのテストに対する最善の策は、クラスによって提供される動作をテストすることです。リポジトリでメソッドを呼び出してから、結果が期待どおりであることを検証します。ただし、ここには隠れたコストがあることに突然気付くでしょう。データベースはテスト実行間で状態を維持し、データベースが既知の状態であることを確認するには、追加のセットアップまたはティアダウンロジックが必要になります。

質問の目的は「ブラックボックス」のテストに関するものでしたが、APIに隠された魔法があることは明らかです。よく知られている状態の問題を解決するための私の好みは、現在のテストにスコープされたインメモリデータベースを使用することです。これにより、環境の考慮事項から分離され、統合テストを並列化できます。現在の設計では、データベース構成をプログラムで導入するための「継ぎ目」がないため、「ヘミングイン」されていると思います。私の経験では、魔法は痛いです。

ただし、既存の設計を少し変更するだけでこの問題は解決し、「魔法」はなくなります。

public class PersonRepository : IPersonRepository
{
      private ConnectionManager _mgr;

      public PersonRepository(ConnectionManager mgr)
      {
         _mgr = mgr;
      }

      public PersonCollection FindPersonsByNameAndCity(string personName, string cityName)
      {
           using (var p = _mgr.CreateProfiler("somekey"))
           {
                 var sp = new PersonStoredProcedure(p);

                 sp.addArguement("name", personName);
                 sp.addArguement("city", cityName);

                 return sp.invoke();
           }
      }
}
于 2011-06-23T15:16:11.830 に答える