20

C# でデータ アクセス レイヤーを単体テストする効果的な方法を探しています。私は主に Java 開発者であり、C# を約 6 か月しか使用していません。過去に、既知の状態データベースに対してテストするために DBUnit というライブラリを使用しました。使用できる同様のアクティブなライブラリを見つけることができませんでした。最も近いのは nDBUnit のようですが、しばらくアクティブになっていません。

C# での方法と理由については、多くの競合する方法があるようです。理想的には、データベースに接続せずにモックを使用してデータ アクセス レイヤーをテストし、別のテスト セットでストア プロシージャを単体テストしたいと考えています。

私が取り組んでいるシステムでは、データ アクセス レイヤーは (Entity Framework を使用せずに) ADO.net を使用して、SQL Server のストア プロシージャを呼び出します。

以下は、私が作業しなければならないサンプルコードです。モック パスをたどるには、(IDbCommand を使用して) SqlCommand をモックしたり、SqlConnection をモックしたりできる必要があります。

だから私の質問は、これを行うための最良の方法と思われるものは何ですか? これまでのところ唯一の方法は、コンストラクターに渡される Proxy オブジェクトを作成して、テスト用にモックされた Sql* オブジェクトを返すことができるようにすることです。

利用可能な C# モック ライブラリをすべて見る機会はまだありません。

public class CustomerRepository : ICustomerRepository
{
   private string connectionString;

   public CustomerRepository (string connectionString)
   {
     this.connectionString = connectionString;
   }

   public int Create(Customer customer)
   {

     SqlParameter paramOutId = new SqlParameter("@out_id", SqlDbType.Int);
     paramOutId.Direction = ParameterDirection.Output;
     List<SqlParameter> sqlParams = new List<SqlParameter>()
     {
       paramOutId,
       new SqlParameter("@name", customer.Name)
     }

     SqlConnection connection = GetConnection();
     try
     {
       SqlCommand command = new SqlCommand("store_proc_name", connection);

       command.CommandType = CommandType.StoredProcedure;

       command.Parameters.AddRange(sqlParams.ToArray());

       int results = command.ExecuteNonQuery();

       return (int) paramOutId.Value;
     }
     finally
     {
       CloseConnection(connection);
     }

   }

}
4

4 に答える 4

26

データベースを既知の状態にし、CustomerRepository をデータベースに対して実行して CustomerRepository をテストできるツールが見つからないのは残念です。ただし、答えは、モックを使用してすべての ADO 呼び出しをモックアウトすることではありません。そうすることで、実際にはロジックをテストしない単体テストを作成することになります。それは、コードが書かれるべきだと思う方法で書かれていることをテストするだけです。

SQL データベースに顧客を作成するためのコマンドとして SQL INSERT を書くことになったとしましょう。ここで、customer テーブルに異なるフィールドが含まれるように (INSERT コマンドが壊れる) 変更を行っており、ストアド プロシージャを使用して顧客を作成する必要があるとします。モックを使用したテストは、テスト対象の実装が壊れていても合格します。さらに、ストアド プロシージャを使用するように実装を修正すると、単体テストは失敗します。単体テストが失敗するはずなのに、システムを修正したときに失敗する場合、単体テストの意味は何ですか?

考えられる代替案については、この質問を参照してください。マークされた答えは、実際に IKVM を使用して C# で DBUnit を使用することになるようです。

したがって、探求し続ける代替手段があるかもしれませんが、ADO 呼び出しをモックすることは、重要なことを実際にテストしない脆弱なテストにつながるだけです。

于 2013-02-24T06:40:22.597 に答える
3

この層の仕事は、コードをデータベースに接続することです。データベース接続と構文に関する知識をカプセル化する必要があります。通常、ドメイン言語をデータベース言語にマップします。単体テストのこの部分を統合テストと見なし、データベース スキーマが実際のデータベースまたはテスト データベースと同等であることをテストします。詳細については、こちらをご覧ください。

于 2013-02-24T05:15:35.437 に答える