web-dev-qa-db-ja.com

xUnitは非同期テストを待機していません

VS 2013では、この非同期テストが失敗することはありません。

XUnit 1.8.0.1539(nugetからインストール)とxUnit Test Runner VS拡張(0.99.5)を使用しています。すべての現在、私の知る限り。

ユニットテストでMoq、AutoFixture、およびFluentAssertions参照もたまたまありますが、それは重要ではないと思います(ただし、そうしている場合は許可します)。

私のソリューションの他の領域で非同期ユニットテストを実行しましたが、それらは機能します。

この新しく作成されたテストで何かが足りないのですが、足りないものや間違っていることはわかりません。

[〜#〜] note [〜#〜] 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コードを書き込む前に非同期テストを開始して失敗したことを確認するより良い方法はありますか?

20

xUnit 1.9が必要async単体テストが正しく機能するために必要です。

24
Stephen Cleary

非同期テストは 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()に渡して、一定時間経過してもテストが完了しない場合に失敗するようにすることができます。書かれているように、非同期メソッドが完了しない場合、テストは無期限にブロックされる可能性があります。

5
Mike Strobel