Необходимо запустить модульные тесты для пользовательского класса, который сильно зависит от классов Office.Interop (COM) - PullRequest
1 голос
/ 05 апреля 2011

У меня есть класс с именем ExcelManager, который отвечает за определение пути к файлу Excel в своем конструкторе и имеет метод, который принимает имя листа в виде строки или индекс листа в виде целого числа, а затем анализирует данные на этом листе. минус заголовки, строит и возвращает DataTable.

Я написал интеграционные тесты, которые успешно тестируют большую часть класса ExcelManager, однако они могут работать только в системе, в которой установлен Excel.

То, что я хочу сделать, это либо сломать класс ExcelManager, чтобы я мог смоделировать электронную таблицу и тестировать без необходимости в Excel, либо найти способ для модульного тестирования и возможного внедрения поддельного объекта в целях тестирования (я не конечно, это лучшая практика), но я не могу найти способ сделать это, вот часть кода Excel Manager:

public ExcelManager(string FilePath)
    {
        try
        {
            application = new ApplicationClass();
        }
        catch (Exception)
        {
            throw new Exception("This feature requires a version of Microsoft Excel developed in 2002 or later, which is not detected on your computer.");
        }

        application.Visible = false;
        application.ScreenUpdating = false;
        application.DisplayAlerts = false;
        this.FilePath = FilePath;

        workbook = application.Workbooks.Open(FilePath, false, false, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss, miss);

    }

Это метод, который открывает указанный лист и создает DataTable Строки headerRng используются для ограничения выбора данными, введенными пользователем, в электронной таблице есть несколько постоянных полей, которые не нужно считывать.

public DataTable GetRangeValue(int SheetIndex)
{
    worksheet = (Worksheet)workbook.Sheets[SheetIndex];

    var headerRng = worksheet.get_Range("A1", miss);
    headerRng = headerRng.get_End(XlDirection.xlToRight);
    headerRng = worksheet.get_Range("A1", headerRng);
    var headerData = (object[,])headerRng.Value2;
    var columnCount = headerData.GetLength(1);

    var last = worksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);

    var dataRng = worksheet.get_Range("A2", last);

    var sheetData = (object[,])dataRng.Value2; // the rest of the code is the DataTable processing

Есть еще один метод, который берет строковое имя для листа и вызывает его с индексом листа.

1 Ответ

0 голосов
/ 05 апреля 2011

Лучше всего было бы передать объект приложения в конструктор вашего класса ExcelManager.

Это позволит вам использовать фальшивый фреймворк для создания поддельной версии excel, передавая его вашему классу в вашем подразделении.тесты.

Недостатком является то, что настройка фиктивного объекта заканчивается тем, что он знает много о внутреннем поведении вашего класса Manager, который является скорее поведенческим тестированием, чем тестированием черного ящика и может быть проблемой при рефакторинге (своего рода хрупкий тестовый кодобоняние)

Не идеально, но совместная работа - слабая область, когда дело доходит до юнит-тестирования.

Есть интересная статья, демонстрирующая такой подход здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...