Как правильно проверить сердцебиение? - PullRequest
3 голосов
/ 28 февраля 2011

Я пишу клиенту, который каждую секунду посылает серверу «сигнал сердцебиения».Клиент вызывает службу WCF в фоновом потоке, чтобы сообщить о своей активности.

Как выполнить модульное тестирование?Нужно ли подождать пару секунд и проверить, не вызывался ли соответствующий метод несколько раз?

Должен ли это быть какой-то сценарий теста вместо этого?Может быть, мне не стоит беспокоиться о непрерывном вызове службы в течение всего жизненного цикла клиентов?

Я могу проверить один вызов службы WCF, но она не проверяет «шаблон пульса».

Я использую подход TDD.(C #, NUnit, Moq)

Любые предложения или примеры?

РЕДАКТИРОВАТЬ:

Я думаю, это не было достаточно ясно.

Это гораздо более простая версия того, что у меня есть:

public class FeedService
{
   private Timer t;

   public FeedService()
   {
      t.Interval = 1000;
      t.Elapsed += TimerElapsed;
      t.Start();
   }

   private void TimerElapsed(object sender, ElapsedEventArgs e)
   {
      t.Stop();
      SendHeartbeat();
      t.Start();
   }
}

... и это мой тест:

[Test]
public void Heartbeat_called_twice_after_2_seconds()
{
  var mockFeedService = new Mock<FeedService>();

  Thread.Sleep(2000);
  mockFeedService.Verify(x => x.SendHeartBeat(), Times.AtLeast(2));
}

У меня есть два вопроса:
1) Почему мой тест всегда терпит неудачу?Что я делаю не так?
2) Стоит ли вообще это проверять?

Ответы [ 3 ]

5 голосов
/ 28 февраля 2011

Функциональность, которую вы хотите проверить, должна быть сначала изолирована.Например, в этом случае есть два аспекта, которые можно проверить.Один из них заключается в том, что компонент сердцебиения фактически отправляет сообщение сердцебиения по назначенному расписанию.Другое - служба получает сообщение.Если вы абстрагируете сервис, вы можете протестировать компонент hearbeat отдельно от реализации сервиса.Это может быть выполнено в модульном тесте, запустив компонентearbeat, затем перейдя в спящий режим и проверив, что ожидаемое количество сообщений было получено реализацией заглушки или фиктивной службы.Тест, обеспечивающий получение службой сообщения, представляет собой интеграционный тест и поэтому не является "чистым" модульным тестом.Однако, поскольку он все равно должен быть проверен, у вас также может быть тестовый пример.

2 голосов
/ 01 марта 2011

Я бы обернул взаимодействие со службой в класс типа "шлюз". Это может быть заменено макетом в вашем тесте, и он может подсчитывать количество звонков, которые вы делаете, или любую статистику, которая вам может понадобиться.

С уважением, Morten

0 голосов
/ 13 марта 2013

Сценарий, который вы хотите проверить - это , строго говоря, интеграционный тест.

Подход, который я применил к аналогичным сценариям построения тестов, заключается в использовании этой удобной функции:

/// <summary>
/// Wait no longer than @waitNoLongerThanMillis for @thatWhatWeAreWaitingFor to return true.
/// Tests every second for the 
/// </summary>
/// <param name="thatWhatWeAreWaitingFor">Function that when evaluated returns true if the state we are waiting for has been reached.</param>
/// <param name="waitNoLongerThanMillis">Max time to wait in milliseconds</param>
/// <param name="checkEveryMillis">How often to check for @thatWhatWeAreWaitingFor</param>
/// <returns></returns>
private bool WaitFor(Func<bool> thatWhatWeAreWaitingFor, int checkEveryMillis, int waitNoLongerThanMillis)
{
    var waitedFor = 0;
    while (waitedFor < waitNoLongerThanMillis)
    {
        if (thatWhatWeAreWaitingFor()) return true;

        Console.WriteLine("Waiting another {0}ms for a situation to occur.  Giving up in {1}ms ...", checkEveryMillis, (waitNoLongerThanMillis - waitedFor));
        Thread.Sleep(checkEveryMillis);
        waitedFor += checkEveryMillis;
    }
    return false;
}

Использование:

// WaitFor (transaction to become failed, checkEverySoOften, waitNoLongerThan)
int wait = (Settings.EventHandlerCoordinatorNoActivitySleepTime + 5) * 1000;
var failedEventExists = WaitFor(() => EventQueueManager.GetFailedEvents(0, 10).TotalRecords > 0, checkEveryMillis: 1000, waitNoLongerThanMillis: wait);

if (!failedEventExists)
    Assert.Fail("Waited longer than " + wait + " without any evidence of the event having been handled.  Expected to failed event on the queue.");

Он использует функции c #, доступные только с .Net4, но, вероятно, в настоящее время подходит большинству разработчиков .Net.

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