Will Parsons
Will Parsons

Reputation: 311

RouteTester issues with optional parameter in routing

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?

Upvotes: 1

Views: 914

Answers (2)

Skadoosh
Skadoosh

Reputation: 2623

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;  
        }
    }

Upvotes: 0

Ron Sher
Ron Sher

Reputation: 181

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

Upvotes: 1

Related Questions