【发布时间】:2012-03-28 07:23:58
【问题描述】:
我首先要说我对单元测试很陌生,我想开始使用 TDD 方法,但现在我正在为一些现有类编写单元测试以验证它们在所有情况下的功能。
我已经能够使用 NUnit 和 Rhino 模拟测试我的大部分代码而没有太多麻烦。但是,我一直想知道单元测试函数最终会在同一个类中调用许多其他方法。我不能做类似的事情
classUnderTest.AssertWasCalled(cut => cut.SomeMethod(someArgs))
因为被测试的类不是假的。此外,如果我正在测试的方法调用了被测类中的其他方法,而这些方法又调用了同一类中的方法,那么我将需要伪造大量值来测试“顶级”方法。由于我也在对所有这些“子方法”进行单元测试,因此如果“SomeMethod”通过了单元测试,我应该能够假设它按预期工作,并且不需要担心那些低级方法的细节。
这是我一直在使用的一些示例代码来帮助说明我的观点(我编写了一个类来使用 NPOI 管理 Excel 文件的导入/导出):
public DataSet ExportExcelDocToDataSet(bool headerRowProvided)
{
DataSet ds = new DataSet();
for (int i = 0; i < currentWorkbook.NumberOfSheets; i++)
{
ISheet tmpSheet = currentWorkbook.GetSheetAt(i);
if (tmpSheet.PhysicalNumberOfRows == 0) { continue; }
DataTable dt = GetDataTableFromExcelSheet(headerRowProvided, ds, tmpSheet);
if (dt.Rows.Count > 0)
{
AddNonEmptyTableToDataSet(ds, dt);
}
}
return ds;
}
public DataTable GetDataTableFromExcelSheet(bool headerRowProvided, DataSet ds, ISheet tmpSheet)
{
DataTable dt = new DataTable();
for (int sheetRowIndex = 0; sheetRowIndex <= tmpSheet.LastRowNum; sheetRowIndex++)
{
DataRow dataRow = GetDataRowFromExcelRow(dt, tmpSheet, headerRowProvided, sheetRowIndex);
if (dataRow != null && dataRow.ItemArray.Count<object>(obj => obj != DBNull.Value) > 0)
{
dt.Rows.Add(dataRow);
}
}
return dt;
}
...
您可以看到 ExportExcelDocToDataSet(在本例中是我的“顶级”方法)调用 GetDataTableFromExcelSheet,后者调用 GetDataRowFromExcelRow,后者调用在同一个类中定义的其他几个方法。
那么,重构此代码以使其更易于单元测试而不必存根由子方法调用的值的推荐策略是什么?有没有办法在被测类中伪造方法调用?
提前感谢您的任何帮助或建议!
【问题讨论】:
标签: c# unit-testing refactoring nunit rhino-mocks