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.AsyncExNuGet 包中获取AsyncContext类型。
三、讨论
对于 async 代码,一条关键准则是避免 async void。强烈建议重构代码,而不是使用 AsyncContext 来对 async void 方法进行单元测试。
(完)
相关阅读:
C# 对 async 方法进行单元测试
C# 对预期失败的 async 方法进行单元测试
C# 对 async void 方法进行单元测试
C# 对数据流网格进行单元测试
C# 对 System.Reactive 可观察对象进行单元测试
C# 通过伪造调度对 System.Reactive 可观察对象进行单元测试
评论
发表评论