我正在为我的数据访问层编写单元测试。为了实现这一点,我已经为SqlCommand(ISqlCommand)创建了一个包装器,以便我可以模拟它的功能。
ISqlCommand command = _connection.GetSqlCommand(sqlCommand);
在我测试的其中一个方法中,正在调用SqlCommand的ExecuteReader方法,我必须返回一个SqlDataReader。
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
在同一方法中,reader.Read将被调用
if (reader.Read())
{
someVariable = reader.GetString(1);
}
我想要的是能够从模拟的command.ExecuteReader()返回一个SqlDataReader对象,其值为Read to Read。可以吗?似乎SqlDataReader只能从正在运行的实际SqlCommand.ExecuteReader实例化并返回SqlDataReader。 完整的相关代码待测。
ISqlCommand command = _connection.GetSqlCommand(sqlCommand);
using (command)
{
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
if (reader.Read())
{
dbVersion = reader.GetString(1);
}
}
编辑:清楚我要问的是什么。 SqlDatareader没有公共构造函数。据我所知,我无法使用该类编写任何测试,因为我无法在不使用SqlCommand对数据库进行合法调用的情况下对其进行实例化。即使尝试创建SqlDataReaderWrapper的接口也无济于事,因为问题是相同的。我不是在尝试编写集成测试(对数据库进行实际调用),因此DataReader似乎无法按原样进行测试。我的问题是,在这种情况下,我可以做什么,将值放入SqlDataReader?
答案 0 :(得分:3)
我假设你没有使用模拟框架。这样做会有所帮助,但您应该按照上面的建议模拟IDataReader。以下是使用RhinoMocks的上一个问题。这可能有所帮助。
另外,我注意到你做了一个ISqlCommand,我建议你使用IDbCommand,它是开箱即用的界面,会让你的测试变得不那么脆弱,因为如果需要的话它会允许替换其他命令对象。
我只是嘲笑数据阅读器,运行良好:
Mock<IDataReader> mockDataReader = new Mock<IDataReader>();
bool success = true;
mockDataReader.Setup(x => x.Read())
.Returns(() => success).Callback(() => success = false);
Assert.IsTrue(mockDataReader.Object.Read());
以下是一个很好的例子:http://www.codeproject.com/Articles/478504/Moq-Mock-Database