C# 对 async void 方法进行单元测试
一、问题
假设需要对某个 async void
方法进行单元测试。
二、解决方案
停止吧!
相对于解决这个问题,竭尽全力避免它才是更应该做的。如果能把 async void
方法改成 async Task
方法,那就再好不过了。
在一些情况下,比如为了满足接口方法签名,某个方法必须是 async void
,那么可以考虑编写两个方法:包含所有逻辑的 async Task
方法,以及调用 async Task
方法并等待结果的 async void
包装。async void
方法能满足架构需求,async Task
方法(包含所有逻辑)则是可以测试的。
如果无法更改方法,而又必须对 async void
方法进行单元测试,也是有办法的。可以使用 Nito.AsyncEx
库中的 AsyncContext
类型:
// 此解决方案并非推荐方案,请阅读完本节的剩余内容
[TestMethod]
public void MyMethodAsync_DoesNotThrow()
{
AsyncContext.Run(() =>
{
var objectUnderTest = new Sut();
objectUnderTest.MyVoidMethodAsync();
});
}
AsyncContext
类型会保持等待状态,直到所有异步操作完成(包括 async void
方法),并会传递被抛出的异常。
可以在
Nito.AsyncEx
NuGet 包中获取AsyncContext
类型。
三、讨论
对于 async
代码,一条关键准则是避免 async void
。强烈建议重构代码,而不是使用 AsyncContext
来对 async void
方法进行单元测试。
(完)
相关阅读:
C# 对 async 方法进行单元测试
C# 对预期失败的 async 方法进行单元测试
C# 对 async void 方法进行单元测试
C# 对数据流网格进行单元测试
C# 对 System.Reactive 可观察对象进行单元测试
C# 通过伪造调度对 System.Reactive 可观察对象进行单元测试
评论
发表评论