1

I have a MVC4 WebApi project with routing that is working correctly with an optional "id" parameter in the route:

        routes.Add(new ApiRouteInfo
        {
            Name = this.AreaName.ToLower() + "_readingsplans",
            RouteTemplate = baseUrl + "/plans/readingalerts/{id}",
            Defaults = new
            {
                area = this.AreaName.ToLower(),
                controller = "ReadingAlerts",
                id = RouteParameter.Optional
            }
        });

When making an actual request the routing works to hit either the GetAll or Get method in the controller methods:

    public HttpResponseMessage GetAll(BaseQueryFilter filter)
    public HttpResponseMessage Get(int id)

But in the unit test, the RouteTester object always hits the Get method, not the GetAll.

Works:

    Assert.AreEqual(ReflectionHelper.GetMethodName((ReadingAlertsController p) => p.Get(It.IsAny<int>())), routeTester.GetActionName());

Fails:

    Assert.AreEqual(ReflectionHelper.GetMethodName((ReadingAlertsController p) => p.GetAll(null)), routeTester.GetActionName());

I've tried passing in an actual filter object instead of null but that doesn't change the outcome at all.

I know I can fix it by creating two different routes, but I'm a bit reluctant since the current routing does work for everything except the unit test.

Any suggestions?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Will Parsons
  • 171
  • 2
  • 12

2 Answers2

1

Did you look at this? It explains a lot about unit testing web api and it may be useful to you.

Ron Sher
  • 181
  • 8
  • That's an interesting article, but unfortunately doesn't help with the issue I'm having. Any testing covered in that is testing the controller method itself, the issue I'm having is when testing just the routing. The biggest thing stumping me is that the routing does work correctly when calling the API, just the RouteTester is having trouble resolving the correct route/method in a test. – Will Parsons Mar 13 '13 at 13:35
  • That article is actually testing out controllers not the route. I am running into this same issue. – Skadoosh Mar 14 '13 at 20:50
0

I found a stackoverflow thread which describes how to test out the route. I am using something similar that I found on the net, but I am willing to try it.

Here is another article with a similar implementation. This is what I am using and having a similar issue with.

--Updated--

I believe I found the fix for the issue. Using the article mentioned above, I replaced the 'GetActionDescriptor()' function with the following:

private HttpActionDescriptor GetActionDescriptor()
    {
        if (controllerContext.ControllerDescriptor == null)
            GetControllerType();

        var actionSelector = new ApiControllerActionSelector();
        var results = actionSelector.GetActionMapping(controllerContext.ControllerDescriptor);
        try
        {
            return actionSelector.SelectAction(controllerContext);
        }
        catch 
        {
            var subActions = results[request.RequestUri.Segments.Last()];
            var action = subActions.FirstOrDefault(a => a.SupportedHttpMethods.First(m => m.Method == request.Method.Method) != null);
            return action;  
        }
    }
Community
  • 1
  • 1
Skadoosh
  • 2,575
  • 8
  • 40
  • 53