在 ASP.NET WebApi 中测试路由配置

2024-02-20

我正在尝试对我的进行一些单元测试WebApi http://www.asp.net/web-api路由配置。我想测试一下路线"/api/super"映射到Get()我的方法SuperController。我已经设置了以下测试,但遇到了一些问题。

public void GetTest()
{
    var url = "~/api/super";

    var routeCollection = new HttpRouteCollection();
    routeCollection.MapHttpRoute("DefaultApi", "api/{controller}/");

    var httpConfig = new HttpConfiguration(routeCollection);
    var request = new HttpRequestMessage(HttpMethod.Get, url);

    // exception when url = "/api/super"
    // can get around w/ setting url = "http://localhost/api/super"
    var routeData = httpConfig.Routes.GetRouteData(request);
    request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;

    var controllerSelector = new DefaultHttpControllerSelector(httpConfig);

    var controlleDescriptor = controllerSelector.SelectController(request);

    var controllerContext =
        new HttpControllerContext(httpConfig, routeData, request);
    controllerContext.ControllerDescriptor = controlleDescriptor;

    var selector = new ApiControllerActionSelector();
    var actionDescriptor = selector.SelectAction(controllerContext);

    Assert.AreEqual(typeof(SuperController),
        controlleDescriptor.ControllerType);
    Assert.IsTrue(actionDescriptor.ActionName == "Get");
}

我的第一个问题是,如果我没有指定完全限定的 URLhttpConfig.Routes.GetRouteData(request);抛出一个InvalidOperationException异常,并显示消息“相对 URI 不支持此操作”。

我的存根配置显然遗漏了一些东西。我更喜欢使用相对 URI,因为使用完全限定的 URI 进行路由测试似乎不合理。

上面配置的第二个问题是我没有测试 RouteConfig 中配置的路由,而是使用:

var routeCollection = new HttpRouteCollection();
routeCollection.MapHttpRoute("DefaultApi", "api/{controller}/");

我如何使用指定的RouteTable.Routes如典型 Global.asax 中的配置:

public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        // other startup stuff

        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        // route configuration
    }
}

此外,我上面列出的可能不是最好的测试配置。如果有更精简的方法,我会洗耳恭听。


我最近正在测试我的 Web API 路由,以下是我的做法。

  1. 首先,我创建了一个助手来将所有 Web API 路由逻辑移至此处:
    public static class WebApi
    {
        public static RouteInfo RouteRequest(HttpConfiguration config, HttpRequestMessage request)
        {
            // create context
            var controllerContext = new HttpControllerContext(config, Substitute.For<IHttpRouteData>(), request);

            // get route data
            var routeData = config.Routes.GetRouteData(request);
            RemoveOptionalRoutingParameters(routeData.Values);

            request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;
            controllerContext.RouteData = routeData;

            // get controller type
            var controllerDescriptor = new DefaultHttpControllerSelector(config).SelectController(request);
            controllerContext.ControllerDescriptor = controllerDescriptor;

            // get action name
            var actionMapping = new ApiControllerActionSelector().SelectAction(controllerContext);

            return new RouteInfo
            {
                Controller = controllerDescriptor.ControllerType,
                Action = actionMapping.ActionName
            };
        }

        private static void RemoveOptionalRoutingParameters(IDictionary<string, object> routeValues)
        {
            var optionalParams = routeValues
                .Where(x => x.Value == RouteParameter.Optional)
                .Select(x => x.Key)
                .ToList();

            foreach (var key in optionalParams)
            {
                routeValues.Remove(key);
            }
        }
    }

    public class RouteInfo
    {
        public Type Controller { get; set; }

        public string Action { get; set; }
    }
  1. 假设我有一个单独的类来注册 Web API 路由(默认情况下在 Visual Studio ASP.NET MVC 4 Web 应用程序项目的 App_Start 文件夹中创建):
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
  1. 我可以轻松测试我的路线:
    [Test]
    public void GET_api_products_by_id_Should_route_to_ProductsController_Get_method()
    {
        // setups
        var request = new HttpRequestMessage(HttpMethod.Get, "http://myshop.com/api/products/1");
        var config = new HttpConfiguration();

        // act
        WebApiConfig.Register(config);
        var route = WebApi.RouteRequest(config, request);

        // asserts
        route.Controller.Should().Be<ProductsController>();
        route.Action.Should().Be("Get");
    }

    [Test]
    public void GET_api_products_Should_route_to_ProductsController_GetAll_method()
    {
        // setups
        var request = new HttpRequestMessage(HttpMethod.Get, "http://myshop.com/api/products");
        var config = new HttpConfiguration();

        // act
        WebApiConfig.Register(config);
        var route = WebApi.RouteRequest(config, request);

        // asserts
        route.Controller.Should().Be<ProductsController>();
        route.Action.Should().Be("GetAll");
    }

    ....

下面是一些注释:

  • 是的,我正在使用绝对 URL。但我在这里没有看到任何问题,因为这些是假 URL,我不需要配置任何内容即可让它们工作,并且它们代表对我们的 Web 服务的真实请求。
  • 如果路由映射代码是在具有 HttpConfiguration 依赖项的单独类中配置的(如上面的示例所示),则无需将路由映射代码复制到测试中。
  • 我在上面的示例中使用了 NUnit、NSubstitute 和 FluentAssertions,但当然,使用任何其他测试框架执行相同的操作是一项简单的任务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ASP.NET WebApi 中测试路由配置 的相关文章

随机推荐

  • 如何等待异步委托

    在 MVA 视频之一中 我看到了下一个构造 static void Main string args Action testAction async gt Console WriteLine In await Task Delay 100
  • 使用多字符分隔符分割字符串

    假设我有以下字符串 Hello there My name is Fred I am 25 5 years old 我想把它分成句子 这样我就有了以下列表 Hello there My name is Fred I am 25 5 year
  • Gitlab 部署脚本 - envsubst:找不到命令

    我有一个带有 CI CD 管道的 gitlab 存储库 它有deploy sh脚本 该脚本可以顺利运行 直到envsubst命令 bin bash set e lt gt deploy via ssh SSH ssh o UserKnown
  • 在 xml 内的图像上绘制视图

    你能帮助我分享你关于如何在android中的图像顶部绘制一个小矩形的知识吗 我有 main xml 和一些小部件 在顶部 有一个图像 我想在该图像上绘制一个矩形 并在应用程序运行时显示这两个矩形 我的 xml 文件如下所示
  • 验证 Rails 中多对多关联的唯一性

    说我有Project 即与多对多关联Tag 我在用着有 许多通过所以我有单独的连接模型 如何创建验证来检查连接模型的唯一性 现在我只有 has many tags through gt taggings uniq gt true 但这并不在
  • MVC 应用程序调试时出错:视图状态 MAC 验证失败

    现在开始表单 第一次 当我开始调试 MVC 应用程序时 我收到此错误 视图状态 MAC 验证失败 如果 该应用程序由 Web 托管 农场或集群 确保 配置指定 相同的validationKey和validation 算法 无法使用自动生成
  • 如何使用 NHibernate 高效地进行 TDD?

    在我看来 大多数人在使用 NHibernate 时都会针对内存中 进程内数据库 例如 SQLite 编写测试 我已经启动并运行了它 但我的第一个测试 使用 NHibernate 总是需要 3 4 秒才能执行 下一个测试运行得更快 我使用 F
  • 是否有 gist.github.com 的内部替代方案可以在防火墙后面运行?

    gist github com 非常方便 但我希望能够运行类似的东西来与我工作的防火墙后面的其他开发人员在内部共享代码示例 因此我不需要一直清理我的代码 只讲代码示例 有这样的事情存在吗 我并不追求大型项目管理工具 只是一种制作一次性要点并
  • OpenShift 无法处理某些 Nodejs 依赖项 (Koa)

    我已经结账了如何在 Openshift 中设置 KoaJS https stackoverflow com questions 26924967 how to setup koajs in openshift但它仍然不起作用 这是我的一部分
  • Apache 作为 ubuntu 上的 root

    好的 我需要运行我的 Apache Web 服务器root 为此我输入了whoami 在终端 它给了我输出 root 但是当我通过执行以下 php 脚本检查我的 apache 服务器是否以 root 用户身份运行时 它给了我输出 nobod
  • 从终端安装 npm 错误

    我正在尝试在我的 mac 中安装节点 我收到以下错误 我从节点站点下载了节点并运行了该包 你们能告诉我为什么我会遇到这个错误 当我执行 npm install 时 MacBook Pro Raj npm install npm ERR in
  • Pickle 无法与 tkinter 一起使用

    我正在用 Tkinter 制作一个小游戏 它有一个使用 pickle 的保存功能 但是 当我尝试保存时 它会弹出以下消息 Exception in Tkinter callback Traceback most recent call la
  • 具有嵌套列表的 Terraform 动态块

    我需要使用 Terraform 在 Pagerduty 中创建升级策略 我想动态创建rule块 然后在其中target块的值来自rule 我不知道如何在目标块内进行第二次调用以使其动态 我有一个列表中的团队列表 locals teams d
  • React Native - 动态列出/需要目录中的文件

    我正在使用 Redux 并希望动态包含目录中的所有文件 redux index js Actions import as authActions from auth authActions import as deviceActions f
  • 如何从图像中仅提取字符?

    我有这种类型的图像 我只想从中提取字符 二值化后 我得到这个图像 img cv2 imread the image jpg gray cv2 cvtColor img cv2 COLOR BGR2GRAY thresh cv2 adapti
  • 如何在密度分布图的两端添加两个阴影

    如何在两端添加阴影 如下图所示 我想添加一端从 0 到 995 和 1 995 到 Inf 我在这里尝试了解决方案https stackoverflow com a 4371473 3133957 https stackoverflow c
  • 如何用 Python 构建提升图(又名增益图)?

    我刚刚使用 scikit learn 创建了一个模型 它可以估计客户对某些报价做出回应的可能性 现在我正在尝试评估我的模型 为此 我想绘制提升图 我理解 lift 的概念 但我很难理解如何在 python 中实际实现它 您可以使用sciki
  • NetLogo 以字符列表的形式读入文件

    我是 NetLogo 新手 我有一个包含一行值的文本文件 ABC CDC BBC 我试图读取该文件的第一行作为字符列表 例如 A B C 我一直在尝试使用文件读取行 但它创建了一个字符串 ABC observer gt file open
  • 如何开始程序生成?

    程序生成 http en wikipedia org wiki Procedural generation最近 由 Spore MMO 等 引起了人们的关注 它似乎是一种有趣 强大的编程技术 我的问题是 您知道有哪些使用程序生成技术的中型项
  • 在 ASP.NET WebApi 中测试路由配置

    我正在尝试对我的进行一些单元测试WebApi http www asp net web api路由配置 我想测试一下路线 api super 映射到Get 我的方法SuperController 我已经设置了以下测试 但遇到了一些问题 pu