Как я могу модульно протестировать службу Windows?
-
09-06-2019 - |
Вопрос
Платформа .NET Framework:2.0 Предпочитаемый язык:C#
Я новичок в TDD (разработке, основанной на тестировании).
Прежде всего, возможно ли вообще модульное тестирование службы Windows?
Класс службы Windows является производным от ServiceBase, который имеет переопределяемые методы,
- На старте
- На остановке
Как я могу вызвать эти методы так, как если бы модульный тест был реальной службой, которая вызывает эти методы в правильном порядке?
На данный момент я вообще провожу модульное тестирование?или интеграционный тест?
Я просмотрел вопрос о службе WCF, но для меня это не имело никакого смысла, поскольку я никогда не имел дела со службой WCF.
Решение
Я бы, вероятно, рекомендовал спроектировать ваше приложение таким образом, чтобы переопределения "OnStart" и "onStop" в службе Windows просто вызывали методы в сборке библиотеки классов.Таким образом, вы можете автоматизировать модульные тесты с использованием методов библиотеки классов, а дизайн также абстрагирует вашу бизнес-логику от реализации службы Windows.
В этом сценарии тестирование самих методов "OnStart" и "onStop" в контексте службы Windows было бы интеграционным тестом, а не тем, что вы бы автоматизировали.
Другие советы
Я провел модульное тестирование служб Windows, не тестируя службу напрямую, а скорее тестируя то, что делает служба.
Обычно я создаю одну сборку для сервиса, а другую - для того, что делает сервис.Затем я пишу модульные тесты для второй сборки.
Самое приятное в таком подходе то, что ваш сервис очень тонкий.По сути, все, что он делает, - это вызывает методы для выполнения нужной работы в нужное время.Ваша другая сборка содержит всю основную часть работы, которую намеревается выполнить ваш сервис.Это делает его очень простым в тестировании и легком повторном использовании или модификации по мере необходимости.
Я бы начал здесь.В нем показано, как запускать и останавливать службы на C#
Пример для начала - это
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch
{
// ...
}
}
Я также тестировал сервисы в основном через консольное приложение, имитируя то, что будет делать сервис.Таким образом, мой модульный тест полностью автоматизирован.
Я бы использовал класс службы Windows (тот, который вы запускаете при запуске / остановке службы) вроде как прокси-сервер для вашей реальной системы.Я не понимаю, чем код, лежащий в основе вашего сервиса, должен отличаться от любого другого программирования.Методы OnStart и onStop - это просто запускаемые события, например нажатие кнопки в графическом интерфейсе.
Таким образом, ваш класс обслуживания Windows - это очень тонкий класс, сравнимый с Windows form.Он вызывает вашу бизнес-логику / domain logic, которая затем делает то, что должна делать.Все, что вам нужно сделать, это убедиться, что методы, которые вы вызываете в ваших OnStart и onStop, работают так, как они должны.По крайней мере, это то, что я бы сделал ;-)
Разработка для тестирования - хорошая стратегия, на что указывают многие ответы, рекомендуя, чтобы ваш OnStart
и OnStop
методы остаются очень тонкими, делегируя их объектам домена.
Однако, если вашим тестам по какой-либо причине необходимо выполнить сервисные методы, вы можете использовать подобный код для вызова их из тестового метода (вызывающий OnStart
в этом примере):
serviceInstance.GetType().InvokeMember("OnStart", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, serviceInstance, new object[] {new string[] {}});
Тестовое окно обслуживания в режиме автоматического отключения питания, завершения работы Тестовое окно обслуживания при отключении от сети, подключении Опция тестового окна обслуживания автозапуск, ручной запуск и т. Д
Парень - это, наверное, лучший ответ.
В любом случае, если вы действительно хотите, вы могли бы просто вызвать в модульном тестировании эти два метода, как описано Документация MSDN но, поскольку они защищены, вам нужно будет использовать Отражение.