This question is in relation to a Previous question I posted.
开发者_开发技巧As mentioned i was able to refactor the original code into two separate classes; I am now trying to test the portion (ParseDataTable) that is not reliant upon Office.Interop objects by mocking the portion (ExcelManager) that is.
When I run the tests my mocked object is only partially working, The GetColumnCount method is being properly mocked and returning my local variable within the ParseDataTable object.
However the GetData mocked method is not being called, the code instead goes into the GetData method on the ExcelManager class
The code used to create the mock:
MockExcel = new Mock<ExcelManager>("testfile.xls",0);
MockExcel.Setup(x => x.GetColumnCount()).Returns(columnCount);
MockExcel.Setup(x => x.GetData()).Returns(mockData);
MockExcel.Setup(x => x.Initialize());
columnCount and mockData are both local variables to the test with data that I am basing my tests on.
The class I am testing:
public class ParseDataTable
{
private const string TableSortOrder = "1 asc, 4 asc, 6 asc";
public DataTable GetRangeValue(ExcelManager excelManager)
{
var columnCount = excelManager.GetColumnCount();
var sheetData = excelManager.GetData();
var value = new DataTable();
for (var j = 1; j <= columnCount; j++)
{
value.Columns.Add(j.ToString());
}
for (var i = 1; i <= sheetData.GetLength(0); i++)
{
var row = value.NewRow();
var emptyCount = 0;
for (var j = 1; j <= columnCount; j++)
{
row[j - 1] = sheetData[i, j] ?? "";
if ((string)row[j-1] == "")
{
emptyCount++;
}
}
//if row is empty then no more data is expected
if (emptyCount == value.Columns.Count) break;
value.Rows.Add(row);
}
excelManager.Dispose();
return sortDataTable(value);
}
private DataTable sortDataTable(DataTable table)
{
table.DefaultView.Sort = TableSortOrder;
table = table.DefaultView.ToTable();
return table;
}
}
Methods within the ExcelManager class that need to be mocked:
public virtual int GetColumnCount()
{
var headerRng = _worksheet.get_Range(HeaderFirstCell, _miss);
headerRng = headerRng.get_End(XlDirection.xlToRight);
headerRng = _worksheet.get_Range(HeaderFirstCell, headerRng);
var headerData = (object[,])headerRng.Value2;
return headerData.GetLength(1);
}
public virtual object[,] GetData()
{
var last = _worksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
var dataRng = _worksheet.get_Range(DataFirstCell, last);
return (object[,])dataRng.Value2;
}
Wouldn't it be much easier if you extracted an interface from ExcelManager as an interface (you can call it IExcelManager, but tell everybody that i came up with the brilliant name :-) ? If you passed that instead your mocking difficulties should be less of a pain.
精彩评论