在单元测试中,async/await相对于阻塞的优势

本文关键字:相对于 await 单元测试 async | 更新日期: 2023-09-27 18:20:09

现代单元测试框架支持等待异步单元测试的结果,如下所示:

public async Task SomeTest()
{
    var result = await SomeMethodAsync();
    // ... Verify the result ...
}

与简单的阻塞相比,使用这种异步方法有什么优势吗?

public void SomeTest()
{
    var result = SomeMethodAsync().Result;
    // ... Verify the result ...
}

异步是否只在并行运行测试时提供好处?

在单元测试中,async/await相对于阻塞的优势

async代码的主要优点是客户端的响应UI和服务器端的可扩展性。对于单元测试,您可以获得一点可伸缩性(这转化为整体速度优势,因为单元测试本质上是突发的)。

但这并不是一个巨大的好处。你的测试(可能)会运行得更快一点。

我通常使用async Task单元测试方法,原因如下:

  • 如果您在上下文中测试代码,那么阻塞可能会导致典型的死锁问题。请注意,某些框架(例如xUnit)在默认情况下总是提供上下文。即使对于其他框架,也经常需要提供一个上下文来对ViewModels进行单元测试
  • await不在AggregateException中包装异常
  • 您确实获得了一点可伸缩性优势,这(理论上)允许您的单元测试总体上运行得更快。假设您的框架并行运行测试
  • 为什么不呢?它们和同步方法一样简单。自2012年以来,async Task单元测试方法得到了各主要单元测试框架的支持

与简单地使用异步方法相比,使用这种异步方法有什么好处吗阻塞?

我认为这真的取决于你正在测试什么。如果你从单元测试框架的角度来看,那么我看不到任何好处。我认为这样的框架不需要在IO方面进行扩展。你所做的唯一一件事就是测试你的异步API的行为。例如,作为库作者,您可以有一个异步端点,并测试当您的代码被不了解如何正确使用库的调用程序同步阻止时会发生什么。

一个例子可能是:

[TestClass]
public class M
{
    [TestMethod]
    public void X()
    {
        var myService = new MyService();
        myService.FetchSomeDataAsync().Result; // Will this deadlock?
    }
}