RouteTester与路由中的可选参数有关

本文关键字:参数 路由 RouteTester | 更新日期: 2023-09-27 18:03:45

我有一个带有路由的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,但这根本不会改变结果。

我知道我可以通过创建两个不同的路由来修复它,但是我有点不情愿,因为当前的路由对除了单元测试之外的所有内容都有效。

有什么建议吗?

RouteTester与路由中的可选参数有关

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

我发现了一个stackoverflow线程,它描述了如何测试路由。我正在使用类似的东西,我在网上找到的,但我愿意尝试一下。

下面是另一篇具有类似实现的文章。这是我正在使用的,并且有类似的问题。

——更新

我相信我找到了解决这个问题的方法。使用上面提到的文章,我用以下代码替换了'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;  
        }
    }