1

From this blog article by Yusef: http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx

I'm trying to set up some unit test for a WebApi project but continue to get:

"No HTTP resrouce was found that matches the request URI http://localhost/api/Filter"

Test case:

[TestMethod]
    public void TestMethod1()
    {
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
        HttpServer server = new HttpServer(config);
        using (HttpMessageInvoker client = new HttpMessageInvoker(server))
        {
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/Filter"))
            {
                request.Content = new StringContent(ValidJSONRequest);
                request.Content.Headers.Add("content", "application/json");
                using (HttpResponseMessage response = client.SendAsync(request, CancellationToken.None).Result)
                {
                    Assert.AreEqual(ValidJSONResponse, response.Content.ReadAsStringAsync().Result);
                }
            }
        };
    }

NB. ValidJSONRequest/ValidJSONResponse are string containing JSON objects.

Running in IIS express this routing works perfectly and behaves as expected and I can't for the life of me work out what's going on? What am I missing?

5
  • I am not sure I understand the point of testing with HttpServer as shown in that blog post. It seems pointless since the in memory server is not configured to run your controller method, or to route requests to it. The response you are getting makes sense since no routes have been set up. Commented Dec 7, 2014 at 18:53
  • @adrift - that's not very helpful. In this case the service is simply performing a transformation operation on a JSON object (there's very little to it) and testing the logic of the controller in isolation is pretty pointless. Besides, surely the config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}"); should configure the route? How do you configure the in memory server to fun the controller method and route requests to it? Commented Dec 7, 2014 at 18:59
  • Unit tests are supposed to test code in isolation. If you aren't trying to unit test your controller method here, what are you trying to test? Commented Dec 7, 2014 at 23:35
  • Are you using OWIN or not OWIN Web API self host? Which version? Are you using Nuget packages or are you referencing an assembly? Or are you referencing a web project? This information is vital to know what's going on. Commented Dec 8, 2014 at 20:56
  • Please, include the controller's method code, and the route configuration in your app, not in your test. I can't reproduce your problem. A similar test works fine in my machine. Also, please, add this line to your unit test code: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; after the config line. You'll get extra info on the error message (apart from the "No HTTP resrouce was found that matches the request URI ...") Commented Dec 9, 2014 at 0:53

2 Answers 2

1

Right, I'm still not sure exactly what's going on here but I've found a workaround.

This blog article contains some details - effectively the controllers context needs to be loaded up into memory... http://www.tugberkugurlu.com/archive/challenge-of-solving-an-asp-net-web-api-self-hosting-problem-no-http-resource-was-found-that-matches-the-request-uri

So how to fix it? Add this test case to the test class and it works fine.

[TestMethod]
public void Filter_Test()
{
    FilterController controller = new FilterController();
}
Sign up to request clarification or add additional context in comments.

1 Comment

For the same effect (loading the assembly you need) you may just declare a member like this: Type valuesControllerType = typeof(ControllersAssembly.ValuesController)
0

The problem is that you're not specifying an id on your tested URL (http://localhost/api/Filter), and the configureed route doesn't have the id configured as optional.

So, either test a ULR that specifies an id, like http://localhost/api/Filter/1, or chagne the route configuration so that the id is optional, like this: instead of

config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");

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

In this way, the tested url will match the DefaultApi route.

Of course, you need a Postxxx method in your controller, because you're trying a POST action, and not specifying an action name neither in the tested URL, nor in the route definition. But, if you say it's working on local IIS, then this method must exist.

1 Comment

Have changed the test case MapHttpRoute to config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }); Have also changed the method name within the FilterController class to "PostFilter". I'm still getting the same error message. Any ideas?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.