5

データ アクセス層の単体テストを書いています。これを実現するために、SqlCommand (ISqlCommand) のラッパーを作成して、その機能をモックできるようにしました。

ISqlCommand command = _connection.GetSqlCommand(sqlCommand);

私がテストしているメソッドの 1 つで、SqlCommand の ExecuteReader メソッドが呼び出され、SqlDataReader を返す必要があります。

SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);

この同じメソッドで reader.Read が呼び出されます

if (reader.Read())
{
    someVariable = reader.GetString(1);
}

私が欲しいのは、モックされた command.ExecuteReader() から SqlDataReader オブジェクトを返すことができるようにすることです。それはできますか?SqlDataReader は、実行されて SqlDataReader を返す実際の SqlCommand.ExecuteReader からのみインスタンス化できるようです。テストする完全な関連コード。

ISqlCommand command = _connection.GetSqlCommand(sqlCommand);

using (command)
{
    SqlDataReader reader =  command.ExecuteReader(CommandBehavior.SingleRow);

    if (reader.Read())
    {
        dbVersion = reader.GetString(1);
    }
}

編集:私が求めていることを明確にするために。SqlDatareader にはパブリック コンストラクターがありません。私が知る限り、SqlCommand を使用してデータベースへの正当な呼び出しを行わないとインスタンス化できないため、そのクラスを使用してテストを作成することはできません。SqlDataReaderWrapper のインターフェイスを作成しようとしても、問題は同じであるため、役に立ちません。私は統合テスト (DB への実際の呼び出しを行う) を作成しようとしていないため、DataReader をそのままテストすることは不可能に思えます。私の質問は、この状況で値を SqlDataReader に入れるためにできることはありますか?

4

1 に答える 1

3

私はあなたがモックフレームワークを使用していないと仮定しています。そうすることは役に立ちますが、おそらく上記のようにIDataReaderをモックする必要があります。これは、RhinoMocksを使用する前の質問です。それが役立つかもしれません。

DataReaderをモックしてRhino.Mocks.Exceptions.ExpectationViolationExceptionを取得する:IDisposable.Dispose(); 期待される#0、実際の#1

また、ISqlCommandを作成したことに気付きました。これは、すぐに使用できるインターフェイスでIDbCommandを使用することをお勧めします。必要に応じて、他のコマンドオブジェクトを置き換えることができるため、テストの脆弱性が低くなります。

データリーダーをモックしただけで、正常に動作します。

 Mock<IDataReader> mockDataReader = new Mock<IDataReader>();
 bool success = true;
 mockDataReader.Setup(x => x.Read())
               .Returns(() => success).Callback(() => success = false);
 Assert.IsTrue(mockDataReader.Object.Read());

これが良い例です:http://www.codeproject.com/Articles/478504/Moq-Mock-Database

于 2012-12-20T17:19:30.507 に答える