我可以创建一个SqlDataReader并提供它的值,而不必从另一个对象(例如SqlCommand.ExecuteReader())返回SqlDataReader吗?

5

我正在为我的数据访问层编写单元测试。为了实现这一目的,我创建了一个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对象,并且这个对象中要有值供我读取。能做到吗?似乎只有在运行并返回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中?


1
我猜你正在寻找IDataRecord接口,它提供了对于DataReader中每一行的列值的访问。你可以简单地将reader强制转换为它:var record = (IDataRecord)reader; - Tim Schmelter
请查看此 MSDN 链接 IDataReader http://msdn.microsoft.com/zh-cn/library/system.data.idatareader.aspx - MethodMan
1个回答

3
我假设您没有使用模拟框架。使用模拟框架会有所帮助,但建议像上面建议的那样模拟IDataReader。这是一个先前的问题,使用了RhinoMocks,可能会有所帮助。 模拟一个DataReader并获得Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose(); 预期#0,实际#1 另外,我注意到您创建了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


嘿,我正在使用Moq作为我的框架。我尝试模拟数据读取器,但无济于事。它没有构造函数,所以即使我为其创建一个包装器的接口,我仍然无法给它测试值。我可能会尝试重构我的代码并完全替换数据读取器,因为我发现它完全无法进行测试。 - Joseph Devlin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接