Steffen Steffen - 2 months ago 37
C# Question

Automatic testing of ApiController

I have an

and would like to test it with unit tests including the routing.

An example:

public class Controller : ApiController
public int Add(int id1, [FromUri] int id2)
return id1 + id2;

I would now like to test this method. I see, that I can test it like an ordinary method. But I would also like to test it with the translation of the URL to the method parameters.

Basically I would like to have an automatic test where I call a URL like
and get a result of 15. Is this somehow possible?


I wrote a little helper class for in-memory integration testing that can be called as part of the test suit.

internal interface IHttpTestServer : IDisposable {
    HttpConfiguration Configuration { get; }
    HttpClient CreateClient();

internal class HttpTestServer : IHttpTestServer {
    HttpServer httpServer;

    public HttpTestServer(HttpConfiguration configuration = null) {
        httpServer = new HttpServer(configuration ?? new HttpConfiguration());

    public HttpConfiguration Configuration {
        get { return httpServer.Configuration; }

    public HttpClient CreateClient() {
        var client = new HttpClient(httpServer);
        return client;

    public void Dispose() {
        if (httpServer != null) {
            httpServer = null;

    public static IHttpTestServer Create(HttpConfiguration configuration = null) {
        return new HttpTestServer(configuration);

And would then use it like this

public async Task HttpClient_Should_Get_OKStatus_From_InMemory_Hosting() {

    using (var server = new HttpTestServer()) {


        var client = server.CreateClient();

        string url = "http://localhost/prefix/10?id2=5";
        var expected = 15;

        var request = new HttpRequestMessage {
            RequestUri = new Uri(url),
            Method = HttpMethod.Get

        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        using (var response = await client.SendAsync(request)) {
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            var result = await response.Content.ReadAsAsync<int>();
            Assert.AreEqual(expected, result);

This will configure an in-memory test server that the test can make calls to using its httpclient. It is in essence an end-to-end integration test.