我刚刚开始使用Moles来模拟一些棘手的遗留代码。本质上,我正在尝试使用SqlDataAdapter来处理Moles。 (顺便说一下,我已成功使用带有SqlDataReader和SqlCommand类的moles。)我试图在下面创建一个“简单”的单元测试示例,我试图让SqlDataAdaptor“填充”提供的DataSet。然后当使用Moles时,我正在模拟从数据集中检索数据的各种调用。我相信我已正确设置DataSet,以便检索数据将返回预期的“moled”对象并做正确的事。
当我运行下面的内容时,我可以看到正在执行FillDataSetString lambda表达式,并且“d”被设置为“moled”ds。但是当Fill方法返回时,传入的DataSet(“dset”)仍然是常规的“DataSet”而不是“moled DataSet”。因此,第一个Assert无法正常运行并抛出IndexOutOfRangeException(“找不到表0”)。在第一个Assert中,我期待在评估dset.Tables [0] .Rows.Count时调用以下“moled”方法:
ds.TablesGet
tables.ItemGetInt32
table.RowsGet
rows.CountGet
但是由于dset不是“moled”DataSet,所以这些调用都不会发生。任何帮助搞清楚Moles正在使用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 :(得分: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");
}
}