Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 337
Elisabeth Avatar asked Jun 18 '15 11:06

Elisabeth


People also ask

How to use the OWIN unit test host?

Using the unit test host. To work with the OWIN Unit Test host, you have to install the NuGet package Microsoft.Owin.Testing in your test project : Once the package is installed, it is possible to create a test server that will host your web api without running IIS. To do that, you have to create an OWIN configuration class in the projet.

How to execute a request in testserver using httpclient?

First line TestServer.Create<Startup> () starts OWIN server using Startup class as a configuration. It is started on some general localhost address. Then we can easily execute a request against this server. Within TestServer we have access to HttpClient to execute any type of request.

How to run OWIN tests without IIs?

As you can see in the sample bellow, the HttpClient takes an custom handler that is provided by the OWIN test server. This is this step that allows us to bypass the use of the http protocol and that allows the tests to run without IIS.

What is OWIN server in WebAPI?

This is a different type of server used in WebAPI. We can still start our API on IIS server, but OWIN gives us an ability to start server in different way. We can migrate our project to OWIN very easiliy.


Video Answer


1 Answers

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.
like image 107
Raja Nadar Avatar answered Oct 10 '22 19:10

Raja Nadar