Почему не удается распознать единичные тесты "асинхронные"?

async void единичные тесты не могут выполняться в Visual Studio 2012:

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async void InvisibleMyTestMethod()
    {
        await Task.Delay(1000);
        Assert.IsTrue(true);
    }
}

Если я хочу иметь асинхронный unit test, метод теста должен вернуть задачу:

[TestMethod]
public async Task VisibleMyTestMethod()
{
    await Task.Delay(1000);
    Assert.IsTrue(true);
}

Почему так? Не то, чтобы я абсолютно нуждался в методе тестирования async void, мне просто интересно. Visual Studio 2012 не дает никаких предупреждений и ошибок при создании метода тестирования async void, хотя он не сможет быть запущен...

Ответ 1

async void методы следует рассматривать как "Огонь и Забыть" - нет способа дождаться их завершения. Если Visual Studio запустит один из этих тестов, он не сможет дождаться завершения теста (отметьте его как успешный) или поймайте все поднятые исключения.

С помощью async Task вызывающий может дождаться завершения выполнения и уловить любые исключения, возникшие во время выполнения.

См. этот ответ для более подробного обсуждения async void vs async Task.

Ответ 2

Это просто потому, что MSTest не поддерживает модульные тесты async void. Это можно сделать, введя контекст, в котором они могут выполняться.

MSTest не поддерживает это, вероятно, потому, что Microsoft решила, что это слишком большая часть изменений для существующих тестов (возможно, что существующие тесты будут тупиковыми, если им был предоставлен неожиданный контекст).

Там нет предупреждений/ошибок компилятора, потому что он отлично подходит для кода С#. Единственная причина, по которой это не работает, - это из-за рамки unit test (т.е. Я считаю, что xUnit поддерживает тесты async void), и было бы грубым нарушением разделения проблем для компилятора С#, чтобы посмотреть на ваш атрибуты, определить, что вы используете MSTest, и решите, что вы действительно не хотите использовать async void.

Ответ 3

В VS2015 я обнаружил, что любые тестовые методы, украшенные асинхронизмом, не будут отображаться в Test Explorer. Я закончил удаление ключевого слова async и заменил ожидающий вызов в тесте на task.Wait() и выполнил мои афертации на task.Result.

Кажется, работает нормально. Еще не пробовал при тестировании на исключение.

var task = TheMethodIWantToTestAsync(someValue);
task.Wait();
var response = task.Result;

Assert.IsNotNull(response);
Assert.IsTrue(response.somevalue);