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

时间:2013-10-11 11:32:36

标签: c# unit-testing visual-studio-2012 async-await c#-5.0

无法在Visual Studio 2012中运行

async void单元测试:

[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不会发出警告或错误,即使它无法运行...

3 个答案:

答案 0 :(得分:73)

async void方法应被视为“Fire and Forget” - 无法等待它们完成。如果Visual Studio要启动其中一个测试,它将无法等待测试完成(将其标记为成功)或捕获任何引发的异常。

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

有关async void vs async Task的详细讨论,请参阅this answer

答案 1 :(得分:21)

这只是因为MSTest不支持async void单元测试。通过引入可以执行的上下文来实现可能

MSTest不支持这一点,可能是因为微软认为对现有测试的改动太多了(如果给出意外情况,现有测试可能会死锁)。

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

答案 2 :(得分:19)

我在VS2015中发现,任何使用async修饰的Test方法都不会在Test Explorer中显示。我最终删除了async关键字并用task.Wait()替换了测试中的await调用,并在task.Result上完成了我的asertions。

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

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

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