The exact situation is I'm doing E2E tests with Protractor.NET (.NET port of AngularJS's Protractor E2E framework) and I would like to make some web requests (and the API -- System.Net.Http.HttpClient
-- has all Async/Task
methods) to Arrange my test before I Act/Assert, only I need to do this same Arrange-ing for several tests.
I'm using xUnit.net as my test runner they use an interface (IUseFixture<T>
) for per-fixture setup code. It would be nice if there was a IAsyncUseFixture<T>
that had a Task SetFixtureAsync(T t);
or something. I don't think such a thing exists. Additionally I don't think constructors can use await
either, and constructors are the only other way to execute the same block of code per-test in xUnit.net.
What are my options? .Result
? Isn't that bad practice (deadlock)?
xUnit has an IAsyncLifetime
interface for async setup/teardown. The methods you need to implement are Task InitializeAsync()
and Task DisposeAsync()
.
InitializeAsync
is called immediately after the class has been created, before it is used.
DisposeAsync
is called just before IDisposable.Dispose
if the class also implements IDisposable
.
e.g.
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);
}
}
I would use AsyncLazy
http://blog.stephencleary.com/2012/08/asynchronous-lazy-initialization.html
In my case I want to run some integration tests against a self hosted web api.
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()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With