How to test WebAPI with In-Memory Hosting

In most cases you want to have integration tests for your , but don’t deploy it on IIS. There is an option which allows to skip IIS pipeline and work only with one. You may create an HTTP server in memory and call the same endpoints as usual. This is easy and allows to cover your API with required tests.

In order to do that you should create an instance of HttpServer class. This class is available after the package is installed Microsoft.AspNet.WebApi.Core. This code may be located in test setup method.

private readonly HttpServer _httpServer;
...
var config = new HttpConfiguration();
WebApiApplication.Configure(config); // config of your Web API
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
_httpServer = new HttpServer(config);

Now you can create a request to the server and call required URL. Below you can find two methods. The 1st creates a request without data, the 2nd one uses Content to pass data to the server.

public HttpRequestMessage CreateRequest(string url, string mthv, HttpMethod method)
{
    var request = new HttpRequestMessage
    {
        RequestUri = new Uri(BASE_URL + url)
    };
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));
    request.Method = method;
    return request;
}

public HttpRequestMessage CreateRequest<T>(string url, string mthv, HttpMethod method, T content,
    MediaTypeFormatter formatter) where T : class
{
    var request = CreateRequest(url, mthv, method);
    request.Content = new ObjectContent<T>(content, formatter);

    return request;
}

The test of some endpoint with GET method could look as follows. It expects URL <host>/api/values returns some value.

[Fact]
public async void TestValues()
{
    using (HttpClient client = httpServerFixture.CreateServer())
    {
        HttpRequestMessage request = httpServerFixture.CreateRequest("api/values", "application/", new HttpMethod("GET"));
        using (HttpResponseMessage response = await client.SendAsync(request))
        {
            Assert.NotNull(response);
        }
    }
}

When you need to get a response result, you should cast Content to specific type.

var content = response.Content as ObjectContent<string>;

See also

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Post

%d bloggers like this: