C# 让单元测试返回异步void是否不好?

C# 让单元测试返回异步void是否不好?,c#,unit-testing,asynchronous,C#,Unit Testing,Asynchronous,我知道让一个方法返回async void是一种不好的做法,因为它使测试变得很困难,但是有没有任何理由让单元测试需要返回async任务而不是async void 基本上这样行吗: [Test()] public async void MyTest() { //Some code to run test //Assert Something } 或者我应该这样做: [Test()] public async Task MyTest() { //Some code to ru

我知道让一个方法返回async void是一种不好的做法,因为它使测试变得很困难,但是有没有任何理由让单元测试需要返回async任务而不是async void

基本上这样行吗:

[Test()]
public async void MyTest()
{
    //Some code to run test
    //Assert Something
}
或者我应该这样做:

[Test()]
public async Task MyTest()
{
    //Some code to run test
    //Assert Something
}
引用斯蒂芬·克利里的话

Void返回异步方法有一个特定的目的:使 异步事件处理程序是可能的。有可能有一个事件 返回一些实际类型,但不适用于 语言;调用返回类型的事件处理程序非常困难 令人尴尬的是,事件处理程序实际上返回 有些事情没有多大意义。事件处理程序自然返回 void,所以异步方法返回void,这样您就可以 异步事件处理程序。然而,异步void的一些语义 方法的语义与异步任务或 异步任务方法

异步void方法具有不同的错误处理语义。当 异常从异步任务或异步任务方法中抛出 异常被捕获并放置在任务对象上。使用异步void 方法,则没有任务对象,因此从 异步void方法将直接在 SynchronizationContext,当异步void方法 开始

最后几句话很好地概括了这一点

长话短说,异步测试方法使用
异步任务

[Test()]
public async Task MyTest()
{
    //Some code to run test
    //Assert Something
}

你真的应该花些时间阅读链接文章。作者在这方面有更多的资源,它将帮助您理解async/await背后的语义。您想知道您的测试是否结束,何时结束,以及测试是否成功完成吗?大多数单元测试运行程序支持
async void
方法(通过使用自定义同步上下文)。尽管如此,使用
async Task
为您的应用程序更干净/安全tests@KevinGosse在您的方法中仍然有很多事情会妨碍测试框架正常工作,即使是在自定义同步上下文中。(例如,有些代码带有<代码> ConfigureAwait(false);< /COD>是所有需要中断的东西。)Servy实际上,同步上下文的<代码>操作完成< /COD>事件只在“代码>异步空虚度< /C>方法结束时触发,即使您在中间使用<代码> ConfigureAwait(false)< /COD>。我肯定有一些边缘情况,但它比看起来更难打破。如果在断言期间发生异常,则无效测试仍会拾取异常。正确吗?只有当其他代码行抛出错误时,问题才会出现?为了安全起见,我将切换到任务返回测试。@NoahLarky:不,它们不会。
任务
使调用代码能够检测完成和异常异步无效不受支持;它们根本不会被运行。