你在模拟测试方面走得很顺利,但是dataReaderMock.Setup(x => x.Read()).Returns(() => records);
是你犯错的地方,因为.Read
返回的是一个布尔值,而不是你的方法从IDataReader
中读取的记录本身。
var dataReader = new Mock<IDataReader>();
dataReader.Setup(m => m.FieldCount).Returns(2); // the number of columns in the faked data
dataReader.Setup(m => m.GetName(0)).Returns("First"); // the first column name
dataReader.Setup(m => m.GetName(1)).Returns("Second"); // the second column name
dataReader.Setup(m => m.GetFieldType(0)).Returns(typeof(string)); // the data type of the first column
dataReader.Setup(m => m.GetFieldType(1)).Returns(typeof(string)); // the data type of the second column
您可以根据自己的口味来排列列,以模拟系统中更多的真实数据类型等。只需确保第一个计数、GetName
数量和GetFieldType
数量同步。
要排列.Read()
,我们可以使用SetupSequence:
dataReader.SetupSequence(m => m.Read())
.Returns(true) // Read the first row
.Returns(true) // Read the second row
.Returns(false); // Done reading
要在测试中使用此方法,您可以将其提取到一个方法中:
private const string Column1 = "First";
private const string Column2 = "Second";
private const string ExpectedValue1 = "Value1";
private const string ExpectedValue2 = "Value1";
private static Mock<IDataReader> CreateDataReader()
{
var dataReader = new Mock<IDataReader>();
dataReader.Setup(m => m.FieldCount).Returns(2);
dataReader.Setup(m => m.GetName(0)).Returns(Column1);
dataReader.Setup(m => m.GetName(1)).Returns(Column2);
dataReader.Setup(m => m.GetFieldType(0)).Returns(typeof(string));
dataReader.Setup(m => m.GetFieldType(1)).Returns(typeof(string));
dataReader.Setup(m => m.GetOrdinal("First")).Returns(0);
dataReader.Setup(m => m.GetValue(0)).Returns(ExpectedValue1);
dataReader.Setup(m => m.GetValue(1)).Returns(ExpectedValue2);
dataReader.SetupSequence(m => m.Read())
.Returns(true)
.Returns(true)
.Returns(false);
return dataReader;
}
(或者,如果这对您的测试类更有意义,您可以将其安排在Setup
上 - 在这种情况下,dataReader
模拟将成为一个字段,而不是返回值)
示例测试。然后可以像这样使用:
[Test]
public void ResovleDataReader_RowCount()
{
var dataReader = CreateDateReader();
var view = ResolveDataReader(dataReader.Object);
Assert.AreEqual(2, view.Count);
}
[Test]
public void ResolveDataReader_NamesColumn1()
{
var dataReader = CreateDataReader();
var view = ResolveDataReader(dataReader.Object);
Assert.AreEqual(Column1, view.Table.Columns[0].ColumnName);
}
[Test]
public void ResolveDataReader_PopulatesColumn1()
{
var dataReader = CreateDataReader();
var view = ResolveDataReader(dataReader.Object);
Assert.AreEqual(ExpectedValue1, view.Table.Rows[0][0]);
}
(我使用过NUnit,但是对于不同的测试框架,测试方法上可能会有不同的属性和不同的断言语法)
另外提一下,我让上面的代码工作起来是通过将ResolveDataReader
更改为internal
并设置InternalsVisibleTo
来实现的,但我假设你已经可以进入这个私有方法了,因为你试图测试它而且已经有了一定的进展。
ResolveDataReader
方法是如何实现的? 我需要查看代码才能给出示例... - Old Fox