【发布时间】:2009-09-02 15:31:31
【问题描述】:
我正在尝试定义一种方法来模拟在不访问的情况下访问数据库的情况......这听起来可能很疯狂,但事实并非如此。
这是一个关于我想测试的方法的示例:
public IDevice GetDeviceFromRepository(string name)
{
IDevice device = null;
IDbConnection connection = new SqlConnection(ConnectionString);
connection.Open();
try
{
IDbCommand command = connection.CreateCommand();
command.CommandText = string.Format("SELECT DEVICE_ID,DEVICE_NAME FROM DEVICE WHERE DEVICE_NAME='{0}'", name);
IDataReader dataReader = command.ExecuteReader();
if(dataReader.NextResult())
{
device = new Device(dataReader.GetInt32(0),dataReader.GetString(1));
}
}
finally
{
connection.Close();
}
return device;
}
我假装模拟 IDataReader,这样我就可以控制正在读取的内容。类似的东西(使用 Moq 框架):
[TestMethod()]
public void GetDeviceFromRepositoryTest()
{
Mock<IDataReader> dataReaderMock = new Mock<IDataReader>();
dataReaderMock.Setup(x => x.NextResult()).Returns(true);
dataReaderMock.Setup(x => x.GetInt32(0)).Returns(000);
dataReaderMock.Setup(x => x.GetString(1)).Returns("myName");
Mock<IDbCommand> commandMock = new Mock<IDbCommand>();
commandMock.Setup(x => x.ExecuteReader()).Returns(dataReaderMock.Object);
Mock<RemoveDeviceManager> removeMock = new Mock<RemoveDeviceManager>();
removeMock.Setup()
RemoveDeviceManager target =new RemoveDeviceManager(new Device(000, "myName"));
string name = string.Empty;
IDevice expected = new Device(000, "myName"); // TODO: Initialize to an appropriate value
IDevice actual;
actual = target.GetDeviceFromRepository(name);
Assert.AreEqual(expected.SerialNumber, actual.SerialNumber);
Assert.AreEqual(expected.Name, actual.Name);
}
我的问题是我是否可以强制方法 GetDeviceFromRepository 用模拟的方法替换 IDataReader。
【问题讨论】:
-
这里的主要问题是我们有一些遗留代码将适合新的解决方案。一项要求是单元测试和自动化构建的覆盖率应超过 95%。我想做的是创建一些单元测试来负责实现这种覆盖,而无需执行过多的折射,也无需访问外部资源(即数据库)来快速执行此测试并每天自动构建几次。这就是采用这种方法的原因。
标签: c# unit-testing moq typemock