Elisabeth
Elisabeth

Reputation: 21216

How to Update the HttpConfiguration AFTER the Owin TestServer creation

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

Answers (1)

Raja Nadar
Raja Nadar

Reputation: 9499

if you want to start the OWIN server once for all tests.

  1. declare a base class for all your test classes
  2. declare a private static readonly variable in your base class for the OWIN Server.

private static readonly TestServer _webServer = TestServer.Create<Startup>();

  1. declare a protected static variable to expose this server to all the tests.

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..

  1. in your Startup.cs, declare a public property...

public static HttpConfiguration HttpConfiguration { get; private set; }

  1. 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);
    
  2. 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.

  1. if you're concerned about your HttpConfiguration just publicly available, then make the Startup class internal and make it visible only to your unit test project.

Upvotes: 1

Related Questions