简体   繁体   English

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

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

As the architecture of ASP.NET Core 1.0 (ex MVC 6 / ASP.NET 5.0) changed significantly, how would one go about unit testing the routing? 随着ASP.NET Core 1.0(前MVC 6 / ASP.NET 5.0)的体系结构发生了重大变化,如何进行单元测试路由?

As an example, I like the libraries such as this one (as for <= MVC 5): https://github.com/AnthonySteele/MvcRouteTester 作为一个例子,我喜欢像这样的库(对于<= MVC 5): https//github.com/AnthonySteele/MvcRouteTester

Something down the lines of fluent extension methods: 一些流畅的扩展方法:

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

Alright... I did ping the ASP.NET team and asked them how they proceeded to do their tests. 好吧......我对ASP.NET团队进行了ping操作并询问他们如何进行测试。

Short answer 简短的回答

You can't unit test without mocking the world. 你不能在不嘲笑世界的情况下进行单元测试。 You have to do integration/functional tests. 你必须进行集成/功能测试。

Slightly longer answer 答案稍微长一些

Routing can come from many places (attributes, pre-defined routes, areas, etc) and can even be altered by middleware. 路由可以来自许多地方(属性,预定义的路由,区域等),甚至可以被中间件更改。 Including all those scenarios in a test would need to setup some massive dependency tree while there is an easier way to test it. 在测试中包括所有这些场景需要设置一些大量的依赖树,同时有一种更简单的方法来测试它。

How they do it. 他们是如何做到的。

Basically, they are creating a TestStartup.cs , self-hosting the app in the test process and hitting itself to see how it behaves. 基本上,他们正在创建一个TestStartup.cs ,在测试过程中自我托管应用程序并自行查看它的行为方式。 They override the results and... that's pretty much it. 他们覆盖了结果......这就是它。

I think I've given you all the possible tools here to actually bootstrap something for yourself. 我想我已经给你了所有可能的工具来实际为自己引导一些东西。

Actually it is not quite hard to write your own route testing framework. 实际上,编写自己的路由测试框架并不是很难。 I implemented route testing in MyTested.AspNetCore.Mvc and it works quickly and without any problem - https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc 我在MyTested.AspNetCore.Mvc中实现了路由测试,它运行迅速且没有任何问题 - https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc

You can take a look at the code but basically, you need the following: 您可以查看代码,但基本上,您需要以下内容:

  1. Mocked IApplicationBuilder to extract registered routes from 模拟IApplicationBuilder从中提取注册路由
  2. Custom HTTP RouteFeature to pass RouteData around 自定义HTTP RouteFeature以传递RouteData
  3. Custom ControllerActionInvoker to extract the binded models and stop MVC from processing the action 自定义ControllerActionInvoker提取绑定模型并阻止MVC处理操作
  4. Test builders and expression parsers to actually prepare and execute the test 测试构建器和表达式解析器以实际准备和执行测试

With these steps in mind, even tests like the following work correctly: 考虑到这些步骤,即使像下面这样的测试也能正常工作:

// 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 Do not write such actions. PS不要写这样的动作。

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

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