1

Moles を使用して、トリッキーなレガシー コードを模倣し始めたところです。本質的に、私は SqlDataAdapter を Moles で動作させようとしています。(ところで、SqlDataReader クラスと SqlCommand クラスでモルを使用して成功しました。) 以下の「単純な」単体テストの例を作成しようとしました。ここでは、SqlDataAdaptor に提供された DataSet を「埋める」ようにさせようとしています。次に、Moles を使用するときは、データ セットからデータを取得する際のさまざまな呼び出しをモックしています。DataSet を正しく設定したので、データを取得すると、期待される「成形された」オブジェクトが返され、正しいことが行われると思います。

以下を実行すると、FillDataSetString ラムダ式が実行され、"d" が "moled" ds に設定されていることがわかります。ただし、Fill メソッドが戻ると、渡された DataSet (「dset」) は、「成形された DataSet」ではなく、通常の「DataSet」のままです。したがって、最初の Assert は正しく動作せず、IndexOutOfRangeException (「テーブル 0 が見つかりません」) をスローします。最初の Assert では、dset.Tables[0].Rows.Count が評価されるときに、次の「モールドされた」メソッドが呼び出されることを期待しています。

    ds.TablesGet
    tables.ItemGetInt32
    table.RowsGet
    rows.CountGet

しかし、dset は「成形された」DataSet ではないため、これらの呼び出しは発生しません。Moles が SqlDataAdapter のデータセット パラメータを使用して何を行っているかを理解するための助けをいただければ幸いです。

以下を機能させるには、"Moles" をインストールし、System.Data、System.Xml を参照し、"System.Data.moles" 参照を作成する必要があります。Moles フレームワークの 0.94.0.0 を使用しており、これを VS.NET 2010 で実行しています。テスト プロジェクトの「ターゲット フレームワーク」は「.NET Framework 4.0」に設定されています。

using System.Data;
using System.Data.Moles;
using System.Data.Common.Moles;
using System.Data.SqlClient;
using System.Data.SqlClient.Moles;
using System.Xml.Serialization;

[TestClass]
public class UnitTest1
{

    [TestMethod]
    [HostType("Moles")]
    public void IsolatedSqlDataAdaptorTest()
    {
        // Arrange
        Dictionary<string, object> backing = new Dictionary<string, object>() 
        {
            {"field", 5},
        };

        MSqlConnection.AllInstances.Open = (c) => { };
        MSqlConnection.AllInstances.Close = (c) => { };
        MSqlDataAdapter.ConstructorStringSqlConnection =
        (@this, cmd, conn) =>
        {
            // Setup a moled DataSet with 1 Table and 1 Row
            MDataRow row = new MDataRow()
            {
                // This is the method that ultimately gets called.
                ItemGetString = (key) => { return backing[key]; },
            };

            MDataRowCollection rows = new MDataRowCollection();
            rows.CountGet = () => { return 1; };
            rows.ItemGetInt32 = (i) => { return row; };

            MDataTable table = new MDataTable();
            table.RowsGet = () => { return rows; };

            MDataTableCollection tables = new MDataTableCollection();
            tables.ItemGetInt32 = (i) => { return table; };

            MDataSet ds = new MDataSet();
            ds.TablesGet = () => { return tables; };

            MSqlDataAdapter sdaMole = new MSqlDataAdapter(@this);
            MDbDataAdapter ddaMole = new MDbDataAdapter(sdaMole)
            {
                FillDataSetString = (d, s) =>
                {
                    d = ds;
                    return 1;
                },
            };
        };

        // Act
        DataSet dset = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter(
            "select something from aTable",
            new SqlConnection());
        da.Fill(dset, "aTable");

        // Assert
        Assert.AreEqual(1, dset.Tables[0].Rows.Count, "Count");
        Assert.AreEqual(5, dset.Tables[0].Rows[0]["field"], "field");
    }
}
4

1 に答える 1

0

Fill メソッドをモックするという @StingyJack の提案に促されて、数か月後にこの質問を再検討したところ、モック要件をサポートするために次のことを思いつきました。データセットが私のモールディングされたデータセットに置き換えられなかった理由については、まだ実際には答えていません。

    [TestMethod]
    [HostType("Moles")]
    public void IsolatedSqlDataAdaptorTestWithFill()
    {
        // Arrange
        MSqlConnection.AllInstances.Open = c => { };
        MSqlConnection.AllInstances.Close = c => { };
        MSqlDataAdapter.ConstructorStringSqlConnection = (@this, cmd, conn) => { };
        MDbDataAdapter.AllInstances.FillDataSetString = (da, ds, s) =>
            {
                var dt = new DataTable(s);
                dt.Columns.Add(new DataColumn("string", typeof(string)));
                dt.Columns.Add(new DataColumn("int", typeof(int)));
                dt.Rows.Add("field", 5);
                ds.Tables.Add(dt);
                return 1;
            };

        // Act
        using (var dset = new DataSet())
        {
            using (var conn = new SqlConnection())
            {
                using (var da = new SqlDataAdapter("select something from aTable", conn))
                {
                    da.Fill(dset, "aTable");
                }
            }

            // Assert
            Assert.AreEqual(1, dset.Tables[0].Rows.Count, "Count");
            Assert.AreEqual("field", dset.Tables[0].Rows[0]["string"], "string");
            Assert.AreEqual(5, dset.Tables[0].Rows[0]["int"], "int");
        }
    }
于 2011-09-27T22:06:02.613 に答える