RouteTester在路由中发出可选参数

时间:2013-03-12 17:52:12

标签: c# unit-testing asp.net-web-api asp.net-web-api-routing

我有一个MVC4 WebApi项目,路由正常,路由中有一个可选的“id”参数:

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

在发出实际请求时,路由会在控制器方法中点击GetAll或Get方法:

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

但是在单元测试中,RouteTester对象总是命中Get方法,而不是GetAll。

使用:

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

失败:

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

我尝试传入一个实际的过滤器对象而不是null,但这根本不会改变结果。

我知道我可以通过创建两条不同的路径来修复它,但我有点不情愿,因为当前路由确实适用于除单元测试之外的所有路由。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

你看过this了吗?它解释了很多关于单元测试web api的内容,它可能对你有用。

答案 1 :(得分:0)

我找到了stackoverflow thread,其中介绍了如何测试路线。我正在使用我在网上发现的类似的东西,但我愿意尝试。

这是另一个具有类似实现的article。这就是我正在使用的并且遇到类似的问题。

<强> - 更新 -

我相信我找到了解决问题的方法。使用上面提到的文章,我用以下内容替换了'GetActionDescriptor()'函数:

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