繁体   English   中英

ASP.NET Core 1.0中的单元测试路由(前MVC 6)

[英]Unit testing routing in ASP.NET Core 1.0 (ex MVC 6)

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

作为一个例子,我喜欢像这样的库(对于<= MVC 5): https//github.com/AnthonySteele/MvcRouteTester

一些流畅的扩展方法:

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

好吧......我对ASP.NET团队进行了ping操作并询问他们如何进行测试。

简短的回答

你不能在不嘲笑世界的情况下进行单元测试。 你必须进行集成/功能测试。

答案稍微长一些

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

他们是如何做到的。

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

我想我已经给你了所有可能的工具来实际为自己引导一些东西。

实际上,编写自己的路由测试框架并不是很难。 我在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>()));

PS不要写这样的动作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM