86

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

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

如果我想进行异步单元测试,测试方法必须返回一个任务:

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

为什么会这样?并不是说我绝对需要一个async void测试方法,我只是好奇。当您构建测试方法时,Visual Studio 2012 不会给出警告或错误,async void即使它无法运行...

4

3 回答 3

93

async void方法应该被视为“一劳永逸”——没有办法等待它们完成。如果 Visual Studio 开始其中一项测试,它将无法等待测试完成(将其标记为成功)或捕获任何引发的异常。

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

有关vs的更多讨论,请参见此答案async voidasync Task

于 2013-10-11T11:42:31.330 回答
24

只是因为 MSTest 不支持async void单元测试。可以通过引入它们可以执行的上下文来做到这一点。

MSTest 不支持这一点,可能是因为 Microsoft 认为它对现有测试的更改太大(如果给定一个意外的上下文,现有测试可能会死锁)。

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

于 2013-10-11T13:44:57.707 回答
23

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

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

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

Assert.IsNotNull(response);
Assert.IsTrue(response.somevalue);
于 2016-03-07T15:07:35.390 回答