为什么不能识别“异步无效”单元测试?


79

async void 单元测试不能在Visual Studio 2012中运行:

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

如果要进行异步单元测试,则测试方法必须返回Task:

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

为什么会这样呢?并不是说我绝对需要一种async void测试方法,我只是很好奇。async void即使无法运行,Visual Studio 2012在构建测试方法时也不会发出警告或错误。

Answers:


83

async void方法应被视为“解雇” –无法等待它们完成。如果Visual Studio要启动这些测试之一,它将无法等待测试完成(将其标记为成功)或捕获引发的任何异常。

使用async Task,调用者可以等待执行完成,并捕获运行时引发的所有异常。

这个答案为更多的讨论async voidVS async Task


3
这不是真的。NUnit确实支持async void测试,并且在此链接中在某种程度上详细说明了支持它的方式和原因。请参阅下面的答案
Anupam

21

仅仅是因为MSTest不支持async void单元测试。这是可能的引入,使他们能够执行环境这样做。

MSTest不支持此功能,可能是因为Microsoft认为对现有测试进行了太多更改(如果给定意外的上下文,则现有测试可能会死锁)。

没有编译器警告/错误,因为它是完全有效的C#代码。它不起作用的唯一原因是由于单元测试框架(即,我相信xUnit确实支持async void测试),对于C#编译器查看属性,确定您的属性,这将完全违反关注点分离正在使用MSTest,并确定您确实不想使用async void


1
在第一个实现(Visual Studio预览)中,将重新识别测试并“运行”。问题在于该方法将在第一次等待时结束,这是测试的结果。
Paulo Morgado

21

我在VS2015中发现,用异步装饰的任何Test方法都不会在Test Explorer中显示。我最终删除了async关键字,并用task.Wait()代替了测试中的await调用,并完成了对task.Result的声明。

似乎工作正常。还没有尝试过异常测试。

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

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

3
不要认为它需要调用task.Wait()作为调用task.Result会在任务尚未完成时自动调用task.Wait()。
stt106
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.