Каков наилучший способ модульного тестирования асинхронного метода? - PullRequest
15 голосов
/ 30 декабря 2008

Кажется, я не могу найти ответ .NET на эту проблему, который, я думаю, был бы довольно распространенным.
Каков наилучший шаблон для модульного тестирования асинхронного метода?

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

Ответы [ 3 ]

10 голосов
/ 30 декабря 2008

Я обычно использую анонимный делегат и ручку ожидания. Для примера у меня в презентаторе есть функция SetRemoteTableName. Когда имя установлено, оно также вызывает событие. Я хочу протестировать это событие, которое вызывается асинхронно. Тест выглядит так:

[TestMethod]
[WorkItem(244)]
[Description("Ensures calling SetRemoteTableName with a valid name works 
              AND raises the RemoteTableNameChange event")]
public void SetRemoteTableNamePositive()
{
  string expected = "TestRemoteTableName";
  string actual = string.Empty;

  AutoResetEvent are = new AutoResetEvent(false);
  SQLCECollectorPresenter presenter = new SQLCECollectorPresenter();
  presenter.RemoteTableNameChange += new EventHandler<GenericEventArg<string>>(
    delegate(object o, GenericEventArg<string> a)
    {
      actual = a.Value;
      are.Set();
    });

  presenter.SetRemoteTableName(expected);
  Assert.IsTrue(are.WaitOne(1000, false), "Event never fired");
  Assert.AreEqual(actual, expected);
}
2 голосов
/ 30 декабря 2008

Разделите код так, чтобы логика была в синхронном бите кода, который вызывается тонкой асинхронной оболочкой.

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

1 голос
/ 30 декабря 2008

есть ли лучший способ, чем просто немного поспать, а затем проверить флаг, который устанавливается обратным вызовом?

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

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