[英]Is it incorrect to call async methods synchronously in unit tests?
我是async / await世界的新手,我正在试图找出为异步方法编写异步单元测试的好处。 也就是说,异步方法的单元测试是否必须异步调用异步方法? 如果它使用Task.Run()同步调用异步方法,会丢失什么? 在后一种情况下,代码覆盖范围不会受到影响,据我所见。
我问这个的原因是因为我们的模拟软件(我们使用TypeMock)不能支持async / await。 ( 他们说这是缺乏支持的合理原因 ,我并不反对他们。)通过在单元测试中同步调用异步方法,我们可以解决这个问题。 但是,我想通过这样做来了解我们是否正在削减任何角落。
例如,假设我有以下异步方法:
public async Task<string> GetContentAsync(string source)
{
string result = "";
// perform magical async IO bound work here to populate result
return result;
}
以下是不起作用的理想单元测试:
[TestMethod()]
public async Task GetContentAsyncTest()
{
string expected = "thisworks";
var worker = new Worker();
// ...mocking code here that doesn't work!
string actual = await worker.GetContentAsync();
Assert.AreEqual(expected, actual);
}
但这很有效,它确实提供了我们需要的代码覆盖率。 这个可以吗?
[TestMethod()]
public void GetContentAsyncTest()
{
string expected = "thisworks";
var worker = new Worker();
// mocking code here that works!
string actual = Task.Run(() => worker.GetContentAsync()).Result;
Assert.AreEqual(expected, actual);
}
必须对异步方法进行单元测试,异步调用async方法吗?
不,但这样做是最自然的。
如果它使用Task.Run()同步调用异步方法,会丢失什么?
真的没什么。 它的性能稍差,但在某种程度上你可能永远不会注意到。
您可能希望使用GetAwaiter().GetResult()
而不是Result
来避免失败测试中的AggregateException
包装。 你也可以直接调用这个方法; 无需将其包装在Task.Run
。
他们说这种缺乏支持是有正当理由的,我并不反对。
哦,我当然不同意他们。 :)
这是否意味着他们无法对迭代器块进行单元测试? 完全相同的推理将适用......
不支持async
单元测试的唯一更严重的问题是,如果被测代码假定其上下文将处理同步。 这很常见,例如,在中等复杂的View模型中。
在这种情况下,您需要安装一个执行async
代码的上下文(例如,我的AsyncContext
类型 ),除非您使用自动提供一个的单元测试框架(截至本文撰写时,只有xUnit执行AFAIK) 。
如果您使用xUnit而不是MSTest,那么您的理想解决方案(异步测试)将起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.