【问题标题】:xUnit not awaiting async testxUnit 不等待异步测试
【发布时间】:2014-05-21 14:58:36
【问题描述】:

在 VS 2013 上,我无法让这个异步测试失败。

我有 xUnit 1.8.0.1539(从 nuget 安装),带有 xUnit Test Runner VS 扩展 (0.99.5)。所有当前,AFAIK。

我碰巧在单元测试中也有 Moq、AutoFixture 和 FluentAssertions 参考,但我认为这并不重要(但我承认以防万一)。

我已经在我的解决方案的其他领域进行了异步单元测试,并且它们有效。

我在这个新创建的测试中遗漏了一些东西,我不知道我遗漏了什么或做错了什么。

注意 SUT 代码并不完整。在我编写代码使测试变为绿色之前,我只是想先获得红灯。

这是测试代码:

using System.Threading.Tasks;
using FluentAssertions;
using Xunit;

namespace MobileApp.Proxy.Test
{
public class WhenRetrievingPriceDataFromClient
{
    [Fact]
    public async Task GroupReportIsReturnedWithSomeData()
    {
        // arrange
        var sut = new Client();

        // act
        var actual = await sut.GetReportGroupAsync();

        // assert

        // Xunit test
        Assert.Null(actual);
        Assert.NotNull(actual);
        // FluentAssertions
        actual.Should().BeNull();
        actual.Should().NotBeNull();
    }
}
}

这里是 SUT 代码:

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
using MobileApp.Proxy.Properties;

namespace MobileApp.Proxy
{
    public class Client
    {
        public async Task<ReportGroup> GetReportGroupAsync()
        {
            return await Task.FromResult(new ReportGroup());
        }
    }
}

显然,这个测试应该失败! Null 和 NotNull 的断言不能都成功,所以我的结论是测试在完成从 SUT 获得响应之前就退出了。

我错过了什么?

或者,我应该在编写 SUT 代码之前启动异步测试以确保它失败吗?

【问题讨论】:

    标签: c# unit-testing asynchronous tdd xunit.net


    【解决方案1】:

    xUnit v1.9 或更高版本支持异步测试。如果您卡在较早的版本中,则需要执行以下操作:

    [Fact]
    public void GroupReportIsReturnedWithSomeData()
    {
         GroupReportIsReturnedWithSomeDataAsync().Wait();
    }
    
    private async Task GroupReportIsReturnedWithSomeDataAsync()
    {
        // arrange
        var sut = new Client();
    
        // act
        var actual = await sut.GetReportGroupAsync();
    
        // assert
    
        // Xunit test
        Assert.Null(actual);
        Assert.NotNull(actual);
        // FluentAssertions
        actual.Should().BeNull();
        actual.Should().NotBeNull();
    }
    

    基本上,测试方法会一直阻塞,直到异步测试方法完成,无论是由于成功完成还是错误(例如,失败的断言)。在出现故障的情况下,异常会通过Wait()传播到主测试线程。

    您可能希望将超时传递给Wait(),这样如果在一定时间后仍未完成,您的测试将失败。如所写,如果异步方法永远不会完成,测试可能会无限期地阻塞。

    【讨论】:

    • 'await' 关键字不与调用'Wait()' 方法做同样的事情吗?但我会尝试你的建议并报告。更新 - 没关系 - 我意识到你刚刚写了一个包装器。我会试试的。
    • 没有。 Wait() 方法会阻塞,直到任务完成。 await 关键字基本上告诉编译器“在此任务完成后继续运行以下代码”。该代码何时继续,以及在哪个线程上,取决于您正在等待的对象类型(在本例中为Task)。如果你在主线程中使用await,你可能会在任务完成之前退出。
    • 对。我要试试这个。但我被引导相信 Xunit 支持异步测试。 (是的,我知道你说过你不使用它)。
    • 基于斯蒂芬回答中的链接,似乎在 xUnit v1.9 中添加了异步测试支持。该链接还表明我的方法是适用于早期版本的方法。
    • 如果在调用这些方法时设置了同步上下文,这种方法很可能会导致死锁。
    【解决方案2】:

    You need xUnit 1.9 使async 单元测试正常工作。

    【讨论】:

    • 噢!我现在意识到我做了什么导致了这个。我没有从 Nuget 安装我想要的每个包,而是依靠 Nuget 的自动包依赖解析器,并安装了“AutoFixture with xUnit.net data theories”包,期望它在实际检索到确切包时检索最新包它依赖的版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2016-03-25
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多