【问题标题】:Unit testing routing in ASP.NET Core 1.0 (ex MVC 6)ASP.NET Core 1.0(前 MVC 6)中的单元测试路由
【发布时间】:2015-08-20 09:49:54
【问题描述】:

随着 ASP.NET Core 1.0(前 MVC 6 / ASP.NET 5.0)的架构发生重大变化,如何对路由进行单元测试?

例如,我喜欢这样的库(对于 https://github.com/AnthonySteele/MvcRouteTester

流畅的扩展方法:

routes.ShouldMap("/").To<HomeController>(x => x.Index());

【问题讨论】:

  • 测试请求是否达到特定操作可能更像是集成测试而不是单元测试。集成测试示例:github.com/aspnet/Mvc/blob/dev/test/…
  • 当然,一切都可以通过集成测试进行测试,但是(恕我直言)进行小型目标单元测试更快,更重要的是 - 更易于维护。在给定的示例中,您只是测试路由,没有设置 HomeController 及其所有依赖项。
  • cmets 来自上面链接的库的作者:github.com/AnthonySteele/MvcRouteTester/issues/65

标签: c# asp.net-mvc unit-testing asp.net-core asp.net-core-mvc


【解决方案1】:

好的...我确实 ping 了 ASP.NET 团队并询问他们如何进行测试。

简答

如果不嘲笑这个世界,就无法进行单元测试。您必须进行集成/功能测试。

答案稍长

路由可以来自许多地方(属性、预定义的路由、区域等),甚至可以被中间件更改。在测试中包含所有这些场景需要设置一些庞大的依赖关系树,同时有一种更简单的测试方法。

他们是如何做到的。

基本上,他们正在创建一个TestStartup.cs,在测试过程中自行托管应用程序并自行查看其行为方式。他们覆盖了结果,并且......就是这样。

我想我已经在这里为你提供了所有可能的工具来实际引导你自己。

【讨论】:

    【解决方案2】:

    其实编写自己的路由测试框架并不难。我在 MyTested.AspNetCore.Mvc 中实现了路由测试,它运行迅速且没有任何问题 - https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc

    您可以看一下代码,但基本上,您需要以下内容:

    1. 模拟 IApplicationBuilder 以从中提取已注册的路由
    2. 自定义 HTTP RouteFeature 以传递 RouteData
    3. 自定义 ControllerActionInvoker 以提取绑定模型并阻止 MVC 处理操作
    4. 测试构建器和表达式解析器以实际准备和执行测试

    考虑到这些步骤,即使像以下这样的测试也可以正常工作:

    // action
    public class NormalController : Controller
    {
        [HttpPost]
        public IActionResult UltimateModelBinding(
            ModelBindingModel model, 
            [FromServices]IUrlHelperFactory urlHelper)
        {
            return null;
        }
    }
    
    // model
    public class ModelBindingModel
    {
        [FromBody]
        public RequestModel Body { get; set; }
    
        [FromForm(Name = "MyField")]
        public string Form { get; set; }
    
        [FromQuery(Name = "MyQuery")]
        public string Query { get; set; }
    
        [FromRoute(Name = "id")]
        public int Route { get; set; }
    
        [FromHeader(Name = "MyHeader")]
        public string Header { get; set; }
    }
    
    // unit test
    MyMvc
        .Routes()
        .ShouldMap(request => request
            .WithLocation("/Normal/UltimateModelBinding/100?myQuery=Test")
            .WithMethod(HttpMethod.Post)
            .WithJsonBody(new
            {
                Integer = 1,
                String = "MyBodyValue"
            })
            .WithFormField("MyField", "MyFieldValue")
            .WithHeader("MyHeader", "MyHeaderValue"))
        .To<NormalController>(c => c.UltimateModelBinding(
            new ModelBindingModel
            {
                Body = new RequestModel { Integer = 1, String = "MyBodyValue" },
                Form = "MyFieldValue",
                Route = 100,
                Query = "Test",
                Header = "MyHeaderValue"
            },
            From.Services<IUrlHelperFactory>()));
    

    P。 S. 不要写这样的动作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      相关资源
      最近更新 更多