web-dev-qa-db-ja.com

xUnit.netのテストセットアップコードでタスクを待ちますか?

正確な状況は、Protractor.NET(AngularJSのProtractor E2Eフレームワークの.NETポート)でE2Eテストを実行していて、いくつかのWebリクエストを作成したいことです(API --_System.Net.Http.HttpClient_--にはすべてAsync /がありますTaskメソッド)実行/アサートする前にテストをアレンジします。いくつかのテストに対してこれと同じアレンジを行う必要があるのは私だけです。

テストランナーとしてxUnit.netを使用していますが、フィクスチャごとのセットアップコードにインターフェイス(_IUseFixture<T>_)を使用しています。 Task SetFixtureAsync(T t);か何かを持った_IAsyncUseFixture<T>_があればいいのにと思います。そんなことはないと思います。さらに、コンストラクターもawaitを使用できるとは思いません。コンストラクターは、xUnit.netでテストごとに同じコードブロックを実行する唯一の他の方法です。

私のオプションは何ですか? _.Result_?それは悪い習慣(デッドロック)ではありませんか?

25

xUnitには、非同期セットアップ/ティアダウン用のIAsyncLifetimeインターフェイスがあります。実装する必要のあるメソッドは、Task InitializeAsync()Task DisposeAsync()です。

InitializeAsyncは、クラスが作成された直後、使用される前に呼び出されます。

クラスがDisposeAsyncも実装している場合、IDisposableIDisposable.Disposeの直前に呼び出されます。

例えば.

public class MyTestFixture : IAsyncLifetime
{
    private string someState;

    public async Task InitializeAsync()
    {
        await Task.Run(() => someState = "Hello");
    }

    public Task DisposeAsync()
    {
        return Task.CompletedTask;
    }

    [Fact]
    public void TestFoo()
    {
        Assert.Equal("Hello", someState);
    }
}
64
Wilka

AsyncLazyを使用します

http://blog.stephencleary.com/2012/08/asynchronous-lazy-initialization.html

私の場合、自己ホスト型WebAPIに対していくつかの統合テストを実行したいと思います。

public class BaseTest() 
{
    private const string baseUrl = "http://mywebsite.web:9999";

    private static readonly AsyncLazy<HttpSelfHostServer> server = new AsyncLazy<HttpSelfHostServer>(async () =>
    {
        try
        {
            Log.Information("Starting web server");

            var config = new HttpSelfHostConfiguration(baseUrl);

            new Startup()
                .Using(config)
                .Add.AttributeRoutes()
                .Add.DefaultRoutes()
                .Remove.XmlFormatter()
                .Serilog()
                .Autofac()
                .EnsureInitialized();

            var server = new HttpSelfHostServer(config);
            await server.OpenAsync();

            Log.Information("Web server started: {0}", baseUrl);

            return server;
        }
        catch (Exception e)
        {
            Log.Error(e, "Unable to start web server");
            throw;
        }
    });

    public BaseTest() 
    {
        server.Start()
    }
}
3
superlogical