根据this discussion,以下两种方法之间应该没有区别:
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);
}
}
Test1
都会通过。Test2
显示在测试运行器中,但它不会运行。在NUnit中,忽略Test2
,并显示以下消息:
测试方法具有非void返回类型,但不期望结果
在XUnit中,Test2
通过。
由于任务仍在等待所有情况下,async
关键字影响NUnit和MSTest测试运行器的含义是什么?也许是一些反思问题?
答案 0 :(得分:8)
听起来那些测试运行者可能正在使用反射来检查返回Task
的方法是否真的是异步方法。这并不意味着该方法的运行方式不同如果它们已经运行 - 但它们只是没有被运行。
就像说:
public string Name { get; set; }
相当于:
private string name;
public Name { get { return name; } set { name = value; } }
在行为方面,它们在逻辑上是相同的,但如果你用反思努力,你可以分辨出来。在这种特殊情况下,还有其他更微妙的差异,但适用相同的一般原则。
在当前的NUnit代码中(在撰写本文时),检测位于AsyncInvocationRegion.cs
。
不可否认,至少异常写一个单元测试返回Task
但没有使用异步方法 - 但这绝非不可能。