Модульное тестирование асинхронного кода - не самая простая вещь в мире, как я узнал, когда писал модульные тесты для моей библиотеки Nito.Async .:)
Сначала вы хотите определить, что вы действительно хотите проверить.Вы просто хотите проверить, выполняется ли асинхронное действие, или вы хотите убедиться, что ваши BGW / задачи правильно синхронизируют свои отчеты о ходе выполнения пользовательского интерфейса?
Тестирование действия довольно простое: просто подождите, пока действиезавершено, а затем проверьте наличие постусловий.(Тем не менее, имейте в виду, что BGW RunWorkerCompleted
будет вызываться в потоке ThreadPool
, если вы не зададите ему контекст синхронизации, как в примере ниже).
Проверка правильности синхронизации (например, для каждого фрагмента кодаработает в правильном потоке) более сложный.
Для каждого теста вам необходимо установить контекст синхронизации.Это будет издеваться над контекстом синхронизации пользовательского интерфейса.Моя библиотека Nito.Async может помочь с этим;он имеет ActionThread
, который является отдельным потоком, который содержит контекст синхронизации, подходящий для владения компонентами EAP (например, BGW) и планирования задач (например, TaskScheduler.FromCurrentSynchronizationContext
).
Он может использоваться следующим образом (используя пример MSTest):
[TestMethod]
public void Test()
{
using (ActionThread thread = new ActionThread())
{
thread.Start();
// Anything passed to Do is executed in that ActionThread.
thread.Do(() =>
{
// Create BGW or call TaskScheduler.FromCurrentSynchronizationContext.
});
// The thread is gracefully exited at the end of the using block.
}
}
Я считаю Thread.CurrentThread.ManagedThreadId
и Thread.CurrentThread.IsThreadPoolThread
самыми простыми способами проверки правильности синхронизации.Если ваш тестовый код запускается из ActionThread.Do
, то он должен синхронизировать свои обновления прогресса (и уведомления о завершении) с этим ActionThread
.
Во многих модульных тестах Nito.Async используется ActionThread
втаким образом, чтобы вы могли искать там различные примеры.