2011-05-18 12 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