C # - модульное тестирование / Mocking - устаревший код - PullRequest
2 голосов
/ 06 сентября 2011

У меня есть следующая логика в более чем десятилетнем коде, для которого я должен написать модульные тесты. Это конкретный класс, и следующая логика лежит в ctor. Есть хороший способ написать модульные тесты / Mocks для такого унаследованного кода. Я использую MSTest / RhinoMocks Framework и VS 2010 IDE с .Net Framework 4.0

public class SomeClass
    {
        /// ctor
        public SomeClass(XmlNode node)
        {
            //Step 1: Initialise some private variable based on attributes values from the node

            //Step 2: Lot of If , else -if statements ---> something like - 

            if (/*attributeValue is something*/)
            {
                // Connect to Db, fetch  some value based on the attribute value. 
                // Again the logic of connecting and fetching is in another concrete class
            }
            else if (/*attributeValue is somthing else*/)
            {
                // fetch a value by loading a config file (this loading and reading of config file 
                // is again a singleton class where config file path is hardcoded)
            }
            else
            {
                // set some private member variable 
            }
        }
    }

Ответы [ 2 ]

6 голосов
/ 06 сентября 2011

Устаревший код модульного тестирования сложен. В общем, вам сначала придется провести рефакторинг, чтобы иметь возможность писать модульные тесты. Лучше всего делать очень маленькие шаги по рефакторингу, чтобы один за другим улучшать тестируемость, оставляя класс в рабочем состоянии. Я бы порекомендовал:

1.) Ввести «воспринимающие» переменные, которые позволяют проверять внутреннее состояние тестируемого класса на ключевых позициях (т.е. до и после вызова БД). Это позволит вам писать тесты, которые проверяют текущее поведение класса (на основе переменных общественного восприятия) без особого рефакторинга. Проверьте поведение класса на основе этих тестов и начните рефакторинг. Переменные восприятия являются временными и должны быть удалены после завершения рефакторинга. Они существуют только для того, чтобы в то же время писать тесты, поэтому вы можете безопасно выполнять рефакторинг.

2.) Один за другим замените ссылки на конкретные классы для ссылок на интерфейсы, которые вы передаете через конструктор. Для синглтона у вас есть два варианта, один из которых заключается в том, чтобы Singleton возвращал специальный экземпляр для модульного тестирования - это требует изменения реализации Singleton, но оставляет тестируемый класс неизменным. Вы можете делать это до тех пор, пока не сможете выполнить рефакторинг для использования зависимости интерфейса для замены Singleton.

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

1 голос
/ 06 сентября 2011

В дополнение к тому, что сказал BrokenGlass, вы можете рассмотреть возможность написания нескольких интеграционных тестов, чтобы убедиться, что весь процесс работает должным образом.Например, если ваше приложение обновляет несколько строк в базе данных, напишите повторяемые тесты, которые соответствуют тестовой базе данных, чтобы вы могли продолжать обеспечивать надлежащую функциональность при рефакторинге и разбивать все это на свободно связанные тестируемые куски.

Нет ничего хуже, чем рефакторинг класса, написание нескольких тестов для него и понимание того, что ваш рефакторинг сломал что-то еще в приложении.

...