Reputation: 21216
The http configuration is setup in te Startup class usually which is bound to the Create method.
But what if I want to start an owin server ONE time for ALL tests but update its http configuration depending on each test needs?
This is not possible. The server object has nothing useful.
using (var server = TestServer.Create<Startup>())
{
var data = server.HttpClient.GetAsync("/api/data);
}
What I want to do for CRUD integration tests is stub the service methods
// Do it ONE time fall ALL tests
WebApiConfig.Register(config);
WebServicesConfig.Register(config);
// Do it individually for each test, Update DI registerations with Fake components per test method
var builder = new ContainerBuilder();
var mockContext = new Mock<TGBContext>();
var mockService = new Mock<SchoolyearService>(mockContext.Object);
mockService.Setup<Task<IEnumerable<SchoolyearDTO>>>(c => c.GetSchoolyearsAsync()).Returns(Task.FromResult(Enumerable.Empty<SchoolyearDTO>()));
// builder.RegisterInstance<TGBContext>(); ****** NO NEED for this it works without registering the ctor parameter dependency
builder.RegisterInstance<SchoolyearService>(mockService.Object);
builder.Update(((AutofacWebApiDependencyResolver)config.DependencyResolver).Container as IContainer);
At the moment I am forced to create a TestServer per Test method.
Thats a total overhead in time.
SOLUTION
Make the HttpConfiguration static and this code should work:
var builder = new ContainerBuilder();
var mockContext = new Mock<TGBContext>();
var mockService = new Mock<SchoolyearService>(mockContext.Object);
mockService.Setup<Task<IEnumerable<SchoolyearDTO>>>(c => c.GetSchoolyearsAsync()).Returns(Task.FromResult(Enumerable.Empty<SchoolyearDTO>()));
builder.RegisterInstance<SchoolyearService>(mockService.Object);
builder.Update(((AutofacWebApiDependencyResolver)Configuration.DependencyResolver).Container as IContainer);
Upvotes: 11
Views: 3922
Reputation: 9499
if you want to start the OWIN server once for all tests.
private static readonly TestServer _webServer = TestServer.Create<Startup>();
protected static TestServer WebServer { get { return _webServer; } }
this should solve your problem of instantiating the web server only once for all the test runs. and if you don't want to initialize the web server so early, you can use lazy instantiation etc. but the point is to make it static and initialize it at definition time itself, so that it is once per app domain.
as for getting access to the HttpConfiguration in your unit tests.. here is one possible way..
public static HttpConfiguration HttpConfiguration { get; private set; }
initialize this variable in the configure method of the Startup.cs class.
HttpConfiguration = new HttpConfiguration();
HttpConfiguration.MapHttpAttributeRoutes();
// do more stuff.. setting resolver etc.
// and then finally
app.UseWebApi(HttpConfiguration);
This HttpConfiguration property is your web api's configuration and because we made it a public property, it should be accessible in your test project and to all tests.
Startup.HttpConfiguration
you can access it to modify the dependency resolver definitions etc.
Startup.HttpConfiguration.DependencyResolver
please note that you can update the DependencyResolver definitions even after you initialize the web server... the updated definitions will still have their effect.
Upvotes: 1