Reputation: 296
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
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