Как использовать фиктивный объект, имитирующий повседневную программу?
В моей программе распорядок дня, похожий на событие будильника. Скажем, когда 2 часа дня (системное время моего компьютера), сделайте что-нибудь для меня.
Что я хочу сделать, так это ускорить период тестирования (я действительно не хочу ждать 4 дня, просматривая ежедневную рутину и проверяя ошибки). Я читал в вики объект Mock, писатель упоминал программу будильника. Я был так рад видеть, но все же, не знаю, как это сделать.
Я новичок в Mock Object, и я программирую на Java. Так что JMock или EasyMock(или любой подобный) могут мне подойти.
Спасибо
4 ответа
Когда вам нужно узнать текущее время, не используйте системные часы напрямую - используйте такой интерфейс, как:
public interface Clock
{
long currentMillis();
}
Затем вы можете реализовать это с системными часами для производства и передать имитатор для тестов, где вы можете установить фиктив на любое время, которое вы хотите.
Тем не менее, вам также нужно будет смоделировать все, что движет вашей системой - вы явно ждете определенное время или что-то еще вызывает ваш код?
Я должен извиниться, так как вы спросили о Java, и я собираюсь пообедать, когда дело доходит до Java, но одно решение состоит в том, чтобы Mock объект DateTime и установить его на желаемое время.
В.NET это будет выглядеть примерно так:
public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}
SystemTime.Now = () => new DateTime(2000,1,1);
От: Работа со временем в тестах
... [A]n программа будильника, вызывающая звонок в определенное время, может получить текущее время из внешнего мира. Чтобы проверить это, тест должен подождать до времени будильника, чтобы узнать, правильно ли он позвонил. Если вместо реального объекта используется фиктивный объект, его можно запрограммировать на предоставление времени звонка (будь то на самом деле это время или нет), чтобы программа будильника могла тестироваться изолированно.
Этот будильник, на который вы ссылаетесь, дает пример насмешки над объектом. На самом деле это не объект, который вы можете использовать из фреймворка.
В основном то, что вы делаете в тесте, это фальсификация часов. Как именно это зависит от дизайна и от того, как вы ожидаете событие, но для простоты (если не чисто), мой подход заключается в том, чтобы иметь метод, который вызывается при запуске события времени, а затем тестировать обе стороны. того, что.
Во-первых, нужно проверить вызов метода и убедиться, что синхронизированное событие выполняет то, что вы ожидаете. Затем смоделируйте этот класс (с помощью JMock предпочтительный способ - сделать его интерфейсом, а вызывающий метод должен реализовать этот интерфейс).
Затем вы передаете макет классу, который обрабатывает время. Здесь снова я бы абстрагировался от проблем потоков / триггеров (таких как проверка системных часов и запуск потока) и имел бы ложные возвращаемые значения, которые по сути запускают событие сразу.
Затем сохраните реальный код, который фактически читает системные часы и запускает поток как можно меньшего размера, и это будет область, которая не подвергается модульному тестированию.
Насмешка относится к юнит-тестированию. Для функциональности, которую вы описываете, я бы отделил триггер (в вашем случае событие будильника) от процесса (независимо от того, что делает ваша "распорядок дня") и провёл модульное тестирование функциональности процесса.
Затем направьте свое внимание на код планирования, который вызовет функциональность вашего процесса. Я бы порекомендовал использовать что-то вроде Quartz для этого, но если вы собираетесь использовать свою роль, то модульный тест для него может работать с реальными системными часами, если вы назначите время запуска на основе текущего значения системных часов, как все будет проверять, происходит ли событие триггера.