Почему асинхронные модульные тесты терпят неудачу, если ключевые слова async/await не используются?
В соответствии с этим обсуждением не должно быть разницы между двумя следующими способами:
public async Task Foo()
{
await DoSomethingAsync();
}
public Task Foo()
{
return DoSomethingAsync();
}
На самом деле, казалось бы, для очень простых методов было бы предпочтительным использовать вызов без ключевых слов async/await, поскольку они устраняют некоторые издержки.
Однако это, по-видимому, не всегда работает в модульных тестах.
MSTest
[TestClass]
public class AsyncTest
{
[TestMethod]
public async Task Test1()
{
await Task.Delay(0);
}
[TestMethod]
public Task Test2()
{
return Task.Delay(0);
}
}
NUnit
[TestFixture]
public class AsyncTest
{
[Test]
public async Task Test1()
{
await Task.Delay(0);
}
[Test]
public Task Test2()
{
return Task.Delay(0);
}
}
XUnit
public class AsyncTest
{
[Fact]
public async Task Test1()
{
await Task.Delay(0);
}
[Fact]
public Task Test2()
{
return Task.Delay(0);
}
}
Так как задачи все еще ждут во всех случаях, что это за ключевое слово async
, которое влияет на тестовые бегуны NUnit и MSTest? Возможно, проблема отражения?
Ответы
Ответ 1
Похоже, что те тест-бегуны могут использовать отражение, чтобы проверить, действительно ли метод, возвращающий Task
, асинхронный метод. Это не означает, что метод будет вести себя по-другому, если они будут запущены, но они просто не запускаются.
Мне нравится говорить, что:
public string Name { get; set; }
эквивалентно:
private string name;
public Name { get { return name; } set { name = value; } }
Они логически одинаковы с точки зрения поведения, но если вы достаточно усердничаете с отражением, вы можете сказать разницу. В этом конкретном случае есть и другие более тонкие различия, но применяется тот же общий принцип.
Похоже, что в текущем коде NUnit (на момент написания) обнаружение находится в AsyncInvocationRegion.cs
.
По общему признанию, по крайней мере, необычно писать unit test, возвращающий Task
, но без использования метода async, но далеко не невозможный.