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