jand187
jand187

Reputation: 296

Using Web API SelfHost for Specflow tests

I have a service project (WebAPI) and a client project that can access the service api. I would like to do a end-to-end test using Specflow (or something similar). I would like to control how the service is configured from the tests, so I can use mocks/stubs/dummies where needed.

Back when WCF was the coolest thing, I did tests like this, by creating instances of my services and hosting them with the standard .Net ServiceHost. All programmatically. It worked like a charm. I would like to do something similar with my Web API service, so I thought that selfhosting was the way to go. But for some reason that is REALLY hard to get to work (as in, I haven't succeeded yet).

Has anyone had any positive results doing something similar? I would prefer not to involve Nance for this, unless it's the only way.

What I need: 1. Launch services programmatically, to control how the service is configured (what dependencies to inject, etc.) 2. Call methods on a client api (or really just doing WebRequests from within the test) hitting the service that I just launched. 3. Performance is not really an issue, but clarity of the code is.

Anyone?

Final solution:

My problem was actually not really related to self hosting. I had a paramter for my Get method with a custom route:

    [Route("api/PermissionChoice/{customerId}")]
    public IEnumerable<PermissionChoice> Get(Guid customerId)

But the custom route is not applied, when starting the selfhost. A configuration, taking the custom route into account, is needed.

The end result looks like this:

    [Fact]
    public void WhatDoesItTest()
    {
        using (WebApp.Start<Startup>(_baseAddress))
        {
            var client = new HttpClient();
            var response = client.GetAsync(_baseAddress + "api/PermissionChoice/4351A155-3F4B-46CE-9C7A-4BA377D5FDDF").Result;
            var permissionChoices = response.Content.ReadAsAsync<IEnumerable<PermissionChoice>>().Result;
            permissionChoices.First().PermissionId.Should().NotBeEmpty();
        }
    }

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "Default",
                routeTemplate: "api/{controller}/{customerId}",
                defaults: new {customerId = RouteParameter.Optional});

            var container = new WindsorContainer();
            container.Install(FromAssembly.This());
            config.DependencyResolver = new WindsorDependencyResolver(container);

            app.UseWebApi(config);
        }
    }

Upvotes: 0

Views: 2220

Answers (1)

satish
satish

Reputation: 2441

You can create a self host and host your controllers and mock the dependencies based on the controller setting as well .

public static class HttpClientFactory
{
    private static HttpClient httpClient;

    public static HttpClient Create()
    {
        if (httpClient == null)
        {
            var baseAddress = new Uri("http://localhost:8081");
            var configuration = new HttpSelfHostConfiguration(baseAddress);
            var selfHostServer = new HttpSelfHostServer(configuration);

            httpClient = new HttpClient(selfHostServer) {BaseAddress = baseAddress};

            return httpClient;
        }
        return httpClient;
    }
}
}

This host the Web Api in the self host environment and you can mock the dependency

Upvotes: 1

Related Questions