Издевательская задача Async

У меня есть следующая ситуация в моих модульных тестах с использованием Moq на .NET 4.0 с использованием Microsoft BCL

Task<MyClass> mockTask = new Task<MyClass>(() => new MyClass());

uploadHelper.Setup().Returns(mockTask);

Task.WaitAll(mockTask);

Проблема, с которой я столкнулась, заключается в том, что Task.WaitAll(mockTask) просто блокирует и никогда не возвращает.

Что я здесь делаю неправильно?

Edit Обратите внимание, что mockTask здесь async здесь, в моем контексте.

Ответ 1

Предлагаемые решения имеют одну проблему: задача может быть завершена временем Returns. Это означает, что ваш unit test демонстрирует другую асинхронную семантику, чем ваш реальный код. Это то, что вы хотите?

Если вы действительно хотите зафиксировать асинхронный характер тестируемого кода, вы не должны использовать метод Returns со значением.

Вместо этого используйте перегрузку Returns, принимающую функцию. Что-то вроде этого:

uploadHelper.Setup().Returns(() => Task.Run(() => new MyClass()));

Таким образом, вы можете быть уверены в том, что используете путь выполнения async.

Ответ 2

Ваша задача не запущена!

Просто используйте:

 Task<MyClass> mockTask = Task.FromResult(new MyClass());

В качестве альтернативы это также работает:

Task<MyClass> mockTask = new Task<MyClass>(() => new MyClass());
mockTask.Start();

Ответ 3

Я использую

Task.Factory.StartNew(() => new MyClass());