2011-08-16 145 views
1

我有一个对象使用Excel文件读取数据,这需要使用IDbConnection,IDbDataAdapterIDbCommand。我使用的适配器填充方法来填充数据的表格,这是我当前如何嘲笑它:使用Moq模拟IDbDataAdapter填充方法

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

这个实现的作品,但我觉得我做得太多嘲笑适配器.. 。 有一个更好的方法吗?

回答

0

不要将这3个对象作为参数传递。而是传递IDataReader,IDataProvider或者像那样返回数据。然后你只是嘲笑这个对象。并且您不需要在包含ExcellReader的项目中引用System.Data。

另外两件事我不喜欢你的代码。 为什么选择TestCase而不是Test?

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

+0

'[TestCase]'用于NUnit,'[Test]'用于Visual Studio测试。另外,我正在为每列创建一个命令,因为我正在根据映射选择特定的单元格。数据不是表格,因此我必须采取个别单元格。 – shuniar

+0

不正确。 [测试]适用于NUnit。 [TestCase]是NUnit中的参数化测试。但是你不通过任何参数。 –

0

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

  1. 编写一个简单的类,它封装了所有数据访问逻辑,这样其他类没有处理DataAdapters和所有废话。
  2. 当你编写单元测试时,不要模拟DataAdapter;而只是模拟你刚刚创建的包装类。
  3. 使数据访问封装逻辑如此简单,以至于它并不需要进行单元测试。如果它需要测试,那么编写集成测试,打击一个小样本数据库。
相关问题