Модульное тестирование с таймаутами - PullRequest
7 голосов
/ 04 июня 2010

Я занимаюсь модульным тестированием класса со свойством, значение которого часто меняется, в зависимости от связи, которую он получает от другого компонента. Если класс не получает никаких сообщений в течение 5 секунд, свойство возвращается к значению по умолчанию.

Мне легко заглушить и смоделировать коммуникационный компонент, чтобы вызвать значения, для которых я хочу проверить. Проблема заключается в том, что если я запускаю свои модульные тесты на машине, которая занята (например, на машине сборки), и имеется достаточно значительная задержка, чтобы заставить свойство по умолчанию работать, тогда мой модульный тест не пройдёт.

Как бы вы проверили, чтобы убедиться, что это свойство имеет правильное значение при моделировании различных условий связи?

Одна идея состоит в том, чтобы реструктурировать мой код, чтобы я мог заглушить ту часть класса, которая контролирует время ожидания. Другой - написать мой модульный тест таким образом, чтобы он мог определить, не прошел ли он из-за тайм-аута, и указать это в результатах теста.

Ответы [ 3 ]

10 голосов
/ 04 июня 2010

Я бы попробовал другой подход. Разработчикам игр часто нужен способ контролировать время игры, например, для быстрой перемотки вперед или синхронизации частоты кадров. Они вводят объект Timer, который считывает тики либо с аппаратных часов, либо с имитированных часов.

В вашем случае вы можете предоставить управляемый таймер для ваших модульных тестов и таймер, который делегирует системное время в производственном режиме. Таким образом, вы можете контролировать время, которое проходит для вашего тестового примера и, следовательно, как тестируемый класс должен реагировать при определенных условиях тайм-аута.

Псевдо-код:

public void testTimeout() throws Exception {
  MockTimerClock clock = new MockTimerClock();

  ClassUnderTest cut = new ClassUnderTest();
  cut.setTimerClock(clock);
  cut.beginWaitingForCommunication();

  assertTrue(cut.hasDefaultValues());
  cut.receiveOtherValues();
  assertFalse(cut.hasDefaultValues());

  clock.tick(5,TimeUnit.SECONDS);
  assertTrue(cut.hasDefaultValues());
  cut.shutdown();
}
3 голосов
/ 04 июня 2010

Есть похожая проблема при использовании DateTime.Now. Айенде описал трюк , который мне понравился:

public static class SystemTime
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

, а затем в вашем тесте:

[Test]
public void Should_calculate_length_of_stay_from_today_when_still_occupied()
{
    var startDate = new DateTime(2008, 10, 1);
    SystemTime.Now = () => new DateTime(2008, 10, 5);

    var occupation = new Occupation { StartDate = startDate };

    occupation.LengthOfStay().ShouldEqual(4);
}

Может быть, вы можете использовать тот же видтрюк на время ожидания?

3 голосов
/ 04 июня 2010

Вы можете сделать свойство тайм-аута настраиваемым, а затем установить его на достаточно высокое значение в своих модульных тестах (или достаточно низкое, если вы хотите выполнить модульное тестирование поведения сброса).

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