2011-05-18 39 views
1

我剛開始使用痣來模擬一些棘手的遺留代碼。本質上,我試圖讓一個SqlDataAdapter與Moles一起工作。 (順便說一句,我已經成功地使用了SqlDataReader和SqlCommand類的moles)。我試圖創建一個「簡單」的單元測試例子,我試圖讓SqlDataAdaptor「填充」提供的DataSet。然後當使用Moles時,我嘲笑從數據集中檢索數據的各種調用。我相信我已經正確地設置了DataSet,以便數據的檢索將返回預期的「moled」對象並做正確的事情。嘲笑SqlDataAdaptor時,爲什麼Moles沒有返回「moled」DataSet?

當我運行下面的代碼時,可以看到正在執行FillDataSetString lambda表達式,並將「d」設置爲「moled」ds。但是當Fill方法返回時,傳入的數據集(「dset」)仍然是常規的「DataSet」而不是「moled DataSet」。因此,第一個Assert不能正常運行並引發IndexOutOfRangeException(「Can not find table 0.」)。在第一個斷言,我期待下面的「moled」方法時dset.Tables [0] .Rows.Count進行評估,以被稱爲:

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

但由於DSET不是不是「moled」數據集,這些呼叫都不會發生。任何幫助找出莫爾斯用SqlDataAdapter的數據集參數做什麼,將不勝感激。爲了得到下面的工作,你必須安裝「Moles」,引用System.Data,System.Xml,創建一個「System.Data.moles」引用。我使用0.94.0.0的Moles框架,並在VS.NET 2010中運行這個框架,並將測試項目的「Target Framework」設置爲「.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"); 
    } 
} 
+0

你真的需要鼴鼠創建整個數據集?爲什麼不扼殺Fill電話? – StingyJack 2011-09-09 12:04:18

+0

好的建議。我已將這一點改寫爲: – Kipp 2011-09-27 21:50:56

回答

0

以新的眼光看待這個問題,數月後建議的提示,通過@StingyJack,嘲笑Fill方法,我想出了以下支持我嘲諷的要求。它仍然沒有真正回答爲什麼數據集沒有被替換爲我的moled數據集。

[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"); 
     } 
    } 
+0

我不確定是否應該將上述標記爲對此問題的答案。建議? – Kipp 2011-09-27 22:08:03

+0

等待兩天(我認爲這是時間限制),並將其標記爲答案,如果它解決了問題。 SO的要點是要確保別人可以從你遇到的同樣的問題中學習,沒有人應該爲了標記自己的物品而作爲答案來下來。 – StingyJack 2011-09-28 12:08:43