【问题标题】:Mock IDbDataAdapter Fill Method With Moq使用 Moq 模拟 IDbDataAdapter 填充方法
【发布时间】:2011-08-16 16:59:01
【问题描述】:

我有一个从 Excel 文件中读取数据的对象,它使用 IDbConnectionIDbDataAdapterIDbCommand。我使用适配器填充方法来填充数据表,这就是我目前模拟它的方式:

[TestCase]
public void TestReadCellsFromSpreadsheetReadsSuccessfully()
{
    var cells = new List<ReportData>
                    {
                        new ReportData { CellId = 1, ExcelCellLocation = "A1"},
                        new ReportData { CellId = 2, ExcelCellLocation = "A2"},
                        new ReportData { CellId = 3, ExcelCellLocation = "A3"},
                        new ReportData { CellId = 4, ExcelCellLocation = "A4"}
                    };

    _mockAdapter.Setup(a => a.Fill(It.IsAny<DataSet>()))
        .Callback((DataSet ds) =>
                      {
                          if (ds.Tables["Table"] == null)
                          {
                              ds.Tables.Add("Table");
                              ds.Tables["Table"].Columns.Add(new DataColumn());
                          }

                          var row = ds.Tables["Table"].NewRow();
                          row[0] = "Test";

                          ds.Tables["Table"].Rows.Add(row);
                      });

    var excelReader = new ExcelReader(_mockConnection.Object, _mockAdapter.Object, _mockCommand.Object);
    excelReader.ReadCellsFromSpreadsheet("Deal Summary", cells);

    _mockCommand.VerifySet(c => c.CommandText = It.IsAny<string>(), Times.Exactly(cells.Count));
    _mockAdapter.VerifySet(a => a.SelectCommand = _mockCommand.Object, Times.Exactly(cells.Count));
    _mockAdapter.Verify(a => a.Fill(It.IsAny<DataSet>()), Times.Exactly(cells.Count));
}

这个实现是可行的,但我觉得我在模拟适配器方面做得太多了......有没有更好的方法来做到这一点?

【问题讨论】:

    标签: unit-testing mocking nunit moq


    【解决方案1】:

    不要将这 3 个对象作为参数传递。而是传递返回数据的 IDataReader、IDataProvider 或类似的东西。然后你只是模拟这个对象。并且您不需要在包含 ExcellReader 的项目中引用 System.Data。

    还有两点我不喜欢你的代码。 为什么选择 TestCase 而不是 Test?

    您确定要分别为每列创建命令和填充数据集吗? (但也许我不明白你的代码)

    【讨论】:

    • [TestCase] 用于 NUnit,[Test] 用于 Visual Studio 测试。另外,我正在为每一列分别创建一个命令,因为我正在根据映射选择特定的单元格。数据不是表格,因此我必须采用单个单元格。
    • 不正确。 [测试] 适用于 NUnit。 [TestCase] 是 NUnit 中的参数化测试。但是你没有传递任何参数。
    【解决方案2】:

    总的来说,我对数据访问有一些规则:

    1. 编写一个简单的类来包装所有数据访问逻辑,这样其他类就不必处理 DataAdapters 和所有这些废话。
    2. 在编写单元测试时,不要模拟 DataAdapters;而只是模拟出你刚刚创建的包装类。
    3. 使数据访问包装逻辑如此简单,以至于实际上不需要进行单元测试。如果确实需要对其进行测试,请编写针对小型示例数据库的集成测试。

    【讨论】:

      猜你喜欢
      • 2010-11-12
      • 2011-01-18
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 2019-07-23
      相关资源
      最近更新 更多