14

I want to run tests against WebAPI project using a popular in-memory hosting strategy.

My tests reside in a separate project.

Here's the start of my test

    [TestMethod]
    public void TestMethod1()
    {
        HttpConfiguration config = new HttpConfiguration();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new {id = RouteParameter.Optional});

        HttpServer server = new HttpServer(config);
        HttpMessageInvoker client = new HttpMessageInvoker(server)
    }

The client is initialized with the HttpServer, establishing the direct client-server connection.

Other than providing route config info, how does HttpServer know which WebAPI project to host?

How to host multiple WebAPI projects at the same time?

Seems HttpServer does some magic to locate WebAPI projects?

Thanks

ton.yeung
  • 4,793
  • 6
  • 41
  • 72
puri
  • 1,829
  • 5
  • 23
  • 42

3 Answers3

17

Web API depends on a service called IAssembliesResolver to get all the assemblies and scans them to find controllers which implement the IHttpController interface.

Now sometimes Web API might be unable to find your controller depending on whether the assembly has been loaded into the current app domain or not. In that scenario you would need to make sure that your assembly is loaded.

Looking at your sample test code, it appears that you are not referring to any type from your Web API project in which case i assume the Web API project's assembly would not be loaded.

Also you seem to be registering the routes again in your test. I would suggest to use the WebApiConfig.Register(HttpConfiguration) of your Web API project to do all the registration stuff. This way you would be testing with the same settings that your Web API project has.

Notes:

  1. When running tests using in-memory server, your requests/responses wouldn't go through the formatters' serialization/deserialization process which is dangerous as you could be having real issues during them. So you would need to make sure to take care about this. Long time back i wrote a blog post regarding this. You can check it out here.

  2. Fiddler tool is very useful in looking at the raw requests/responses to diagnose any issues. You would be loosing this ability if you are doing in-memory testing though.

Luke Puplett
  • 42,091
  • 47
  • 181
  • 266
Kiran
  • 56,921
  • 15
  • 176
  • 161
  • I am attempting to implement this as well, but when I make a call to the server from the client, I just get a 500 error, with no exceptions thrown or any other kind of diagnostic info. Any way to debug this? – Jason Coyne May 29 '15 at 16:54
1

Web Api should find all your controllers that inherit from ApiController. As long as all your controllers are in the same solution it should work just fine. I have a very similar setup that runs tests using the in-memory httpserver against controllers in another project. This gives me the ability to do very fast "integration" tests in my unit test project.

Joshua Peterson
  • 1,026
  • 7
  • 8
  • 1
    How does HttpServer know what WebAPI service to host? We have just provided route information, nothing more as per my example. Reflection? But then what feeds into that routine? – puri May 29 '13 at 17:34
0

Just make sure that you are invoking any controller from the web api project into your separate project to ensure that web api project is loaded in in-memory.Example:

[TestMethod]
public void TestMethod1()
{

 //// So that the web api project is loaded in-memory
 {webapi Project name}.Controller.{controllerName} = new {controller name}() ;
    HttpConfiguration config = new HttpConfiguration();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new {id = RouteParameter.Optional});

    HttpServer server = new HttpServer(config);
    HttpMessageInvoker client = new HttpMessageInvoker(server)
}