Необходимо смоделировать пользовательский класс для целей модульного тестирования - PullRequest
5 голосов
/ 07 апреля 2011

Этот вопрос относится к Предыдущему вопросу Я отправил.

Как уже упоминалось, я смог изменить исходный код на два отдельных класса; Сейчас я пытаюсь протестировать часть (ParseDataTable), которая не зависит от объектов Office.Interop, путем насмешки над частью (ExcelManager), которая является.

Когда я запускаю тесты, мой смоделированный объект работает только частично, метод GetColumnCount корректно проверяется и возвращает мою локальную переменную в объекте ParseDataTable.

Тем не менее, смоделированный метод GetData не вызывается, вместо этого код переходит в метод GetData класса ExcelManager

Код, использованный для создания макета:

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 и mockData являются локальными переменными для теста с данными, на которых я основываю свои тесты.

Класс, который я тестирую:

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

Методы в классе ExcelManager, которые необходимо смоделировать:

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

1 Ответ

1 голос
/ 12 апреля 2011

Не было бы намного проще, если бы вы извлекли интерфейс из ExcelManager в качестве интерфейса (вы можете назвать его IExcelManager, но скажите всем, что я придумала блестящее имя :-)?Если вы прошли это, вместо этого ваши насмешливые трудности должны быть меньше боли.

...