将Mock datareader传递给数据加载方法

时间:2018-02-07 09:11:13

标签: c# unit-testing datatable moq

我正在尝试对一段代码进行单元测试,该代码具有以下一行

var datatable = new DataTable();
datatable.Load(datareader);

所以我想在load方法中传递模拟数据读取器对象。我希望数据表类从数据读取器加载我的存根值。

我在我的测试用例中完成了以下设置

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);

我可以在调试时看到我的数据读取器已成功模拟。但是当执行DataTable.Load时。 DataTable对象没有任何值。我可以看到列名已加载但没有在行中看到任何值。即使行号正确但在任何行中都没有值。

我猜是DataTable.Load不使用GetValue从数据读取器中获取,我的测试用例是针对数据读取器的GetValue方法设置的。我也尝试设置GetString方法,但它仍然没有用。我知道应该设置哪种数据读取器方法,以便数据表能够正确加载值?

1 个答案:

答案 0 :(得分:0)

我参加聚会有点晚了,但我发现以下对我有用(行也很多)

var dataReader = new Mock<DbDataReader>();
dataReader.Setup(c => c.FieldCount).Returns(2);

dataReader.Setup(c => c.GetFieldType(0)).Returns(typeof(string));
dataReader.Setup(c => c.GetFieldType(1)).Returns(typeof(string));

// Columns
dataReader.Setup(c => c.GetName(0)).Returns("Column1");
dataReader.Setup(c => c.GetName(1)).Returns("Column2");

dataReader.Setup(m => m.GetOrdinal("Column1")).Returns(0);

// Rows
// NOTE: Unfortunately this only works for a single row.
dataReader.Setup(c => c.GetValues(It.IsAny<object[]>())).Callback<object[]>(
    (values) =>
        {
            values[0] = "Column1 Value";
            values[1] = "Column2 Value";
        }
).Returns(2);

// Read one row
dataReader.SetupSequence(c => c.Read()).Returns(true).Returns(false);

这不是一个优雅的解决方案,但是是我用作临时解决方案的一种非常快速的解决方法。