首页 > 编程语言 >精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性

精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性

时间:2024-04-22 09:02:59浏览次数:18  
标签:Core Asp 请求 context 中间件 测试 var 路由

引言

在上一章节我们实战了在Asp.Net Core中的项目实战,这一章节讲解一下如何测试Asp.Net Core的中间件。

TestServer

还记得我们在集成测试中提供的TestServer吗?
TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。包含了用于在测试环境中模拟 ASP.NET Core 应用程序的类和方法。通过使用 TestServer,开发人员可以在测试中模拟整个应用程序的运行环境,包括中间件的执行,从而进行集成测试和端到端测试。

中间件可以使用 TestServer 单独测试。 这样便可以:

  • 实例化只包含需要测试的组件的应用管道。
  • 发送自定义请求以验证中间件行为。

优点:

  • 请求会发送到内存中,而不是通过网络进行序列化。
  • 这样可以避免产生额外的问题,例如端口管理和 HTTPS 证书。
  • 中间件中的异常可以直接流回调用测试。
  • 可以直接在测试中自定义服务器数据结构,如 HttpContext

实战

VS 新建测试项目dotNetParadise.MiddlerWareTest

Nuget 安装Microsoft.AspNetCore.TestHost

PM> NuGet\Install-Package Microsoft.AspNetCore.TestHost -Version 8.0.4

既然我们是要测试中间件 那首先得先在我们的Sample.Api中创建一个中间件

定义MyMiddleware中间件

public class MyMiddleware(RequestDelegate next)
{
    public async Task InvokeAsync(HttpContext context)
    {
        // 在请求处理前执行的逻辑
        context.Response.ContentType = "text/plain";
        context.Response.Headers.TryAdd("X-Custom-Header", "CustomValue");
        await context.Response.WriteAsync("Test My Middleware");
        // 调用下一个中间件
        await next(context);

        // 在请求处理后执行的逻辑
        await context.Response.WriteAsync("Middleware Test Completed");
    }
}

定义测试类

        // Arrange
        using var host = await new HostBuilder()
            .ConfigureWebHost(webBuilder =>
            {
                webBuilder
                    .UseTestServer()
                    .ConfigureServices(services =>
                    {
                        // 在这里可以注入服务
                    })
                    .Configure(app =>
                    {
                        app.UseMiddleware<MyMiddleware>();
                    });
            })
            .StartAsync();

        // Act
        var response = await host.GetTestClient().GetAsync("/");

        // Assert
        response.EnsureSuccessStatusCode(); // 确保请求成功
        var responseContent = await response.Content.ReadAsStringAsync();
        Assert.Contains("Test My Middleware", responseContent);
        Assert.Contains("Middleware Test Completed", responseContent);

Run Test

image

使用 HttpContext 发送请求

可以使用 TestServer 来设置测试环境,并创建一个模拟的 HttpContext对象来代表一个请求

    [Fact]
    public async Task TestMiddleware_ExpectedResponse()
    {
        using var host = await new HostBuilder()
            .ConfigureWebHost(webBuilder =>
            {
                webBuilder
                    .UseTestServer()
                    .ConfigureServices(services =>
                    {
                    })
                    .Configure(app =>
                    {
                        app.UseMiddleware<MyMiddleware>();
                    });
            })
            .StartAsync();

        var server = host.GetTestServer();
        server.BaseAddress = new Uri("http://localhost");

        var context = await server.SendAsync(c =>
        {
            c.Request.Method = HttpMethods.Get;
            c.Request.Path = "/";
            c.Request.Host = new HostString("localhost");
            c.Request.Scheme = "http";
        });
        //act
        Assert.True(context.RequestAborted.CanBeCanceled);
        Assert.Equal(HttpProtocol.Http11, context.Request.Protocol);
        // 验证响应
        Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
        var customHeader = context.Response.Headers["X-Custom-Header"].ToString();
        Assert.Equal("CustomValue", customHeader);
    }

使用 SendAsync 的好处包括:
通过设置 HttpContext 的任何属性,从而精确控制请求的各个方面。相比于使用 HttpClientSendAsync 通常更快,因为它绕过了网络层。
集成测试:这是测试整个请求处理管道(包括所有中间件)的好方法。
然而,它也有一些限制:

局限性
SendAsync 主要用于集成测试,而不是单元测试。它测试的是整个请求处理流程,而不是单个组件。
模拟限制:虽然你可以设置 HttpContext 的许多属性来模拟请求,但某些方面(如用户认证状态或外部依赖项)可能难以完全模拟。

添加请求路由

这个比较好理解,就是在TestServer中添加路由的功能和Asp.Net Core中添加路由基本一致

    [Fact]
    public async Task TestWithEndpoint_ExpectedResponse()
    {
        using var host = await new HostBuilder()
            .ConfigureWebHost(webBuilder =>
            {
                webBuilder
                    .UseTestServer()
                    .ConfigureServices(services =>
                    {
                        services.AddRouting();
                    })
                    .Configure(app =>
                    {
                        app.UseRouting();
                        //app.UseMiddleware<MyMiddleware>();
                        app.UseEndpoints(endpoints =>
                        {
                            endpoints.MapGet("/hello", () =>
                                TypedResults.Text("Hello Tests"));
                        });
                    });
            })
            .StartAsync();

        var client = host.GetTestClient();

        var response = await client.GetAsync("/hello");

        Assert.True(response.IsSuccessStatusCode);
        var responseBody = await response.Content.ReadAsStringAsync();
        Assert.Equal("Hello Tests", responseBody);

    }

在测试场景中,添加请求路由的好处主要体现在以下几个方面:

  • 模拟真实环境:
    通过添加请求路由,你可以模拟出与真实生产环境相似的请求处理流程。这使得测试更加接近实际使用情况,从而提高了测试的可靠性和有效性。

  • 控制测试的粒度:
    你可以针对特定的路由进行精确测试,确保每个路由都能正确响应并返回预期的结果。这有助于发现潜在的路由错误或逻辑问题,提高了测试的精度。

  • 隔离测试:
    在测试过程中,你可以通过配置路由来隔离特定的功能或组件,从而避免其他部分的干扰。这种隔离测试有助于更准确地定位问题,提高了测试的效率。

  • 模拟异常场景:
    通过配置路由,你可以模拟各种异常场景,如路由不存在、参数错误等。这有助于测试应用程序在异常情况下的响应和处理能力,提高了应用程序的健壮性。

  • 自动化测试:
    在自动化测试框架中,添加请求路由可以使得测试用例更加易于编写和执行。通过发送请求到特定的路由并验证响应,你可以自动化地检查应用程序的功能和性能。

最后

本章我们探讨了如何在Asp.Net Core项目中测试中间件的方法和技巧。通过使用TestServerHttpContext发送请求,我们可以模拟整个应用程序的运行环境,从而进行集成测试和端到端测试。同时,我们也介绍了如何添加请求路由来模拟不同的场景,并对中间件的行为进行验证。

通过测试中间件,我们可以确保其在处理请求时的行为符合预期,提高应用程序的稳定性和可靠性。测试不仅可以帮助发现潜在的问题,还可以在开发过程中及早发现和解决 bug,提高代码质量和开发效率。

标签:Core,Asp,请求,context,中间件,测试,var,路由
From: https://www.cnblogs.com/ruipeng/p/18149582

相关文章

  • aspNet http中的请求参数
    问题[Route("api/[controller]")][ApiController]publicclassUserController:ControllerBase{privatereadonlyUserManager<IdentityUser>_userManager;publicUserController(UserManager<IdentityUser>userManager){......
  • 中间件 ZK分布式专题与Dubbo微服务入门 8-6 使用tomcat启动dubbo服务
    0课程地址https://coding.imooc.com/lesson/201.html#mid=12744 1重点关注1.1本节内容使用tomcat启动dubbo服务tomcat启动dubbo服务的弊端    2课程内容2.1tomcat启动dubbo服务的弊端tomcat本身也是软件,占用内存  ......
  • ASP.NET MVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(1)
    ASP.NETMVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(1) 本系列的的角色权限管理主要采用Dotnet MVC4工程内置的权限管理模块Simplemembership实现,主要有关文件是InitializeSimpleMembershipAttribute.cs和AccountModels.cs下面是对这两个文件的了解和改造 WebSe......
  • 如何在ASP.NET MVC中的角色中设置权限?
    如何在ASP.NETMVC中的角色中设置权限? 在ASP.NETMVC中,可以通过使用角色和权限来实现访问控制。下面是在ASP.NETMVC中设置角色权限的步骤:创建角色:首先,需要创建角色来表示不同的用户组。可以使用ASP.NET提供的RoleManager类来创建和管理角色。可以在IdentityConfig.cs文......
  • ASP.NET MVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6)
    ASP.NETMVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6) 快过年了,公司事情忙,好几天没有继续写博客,今天开始写账户模块系统登录,账户管理以及登录日志,首先新建登录日志数据表: ViewCode然后更改模型:AccountModels.cs ViewCode创建登录日志模型:M_UsersLoginLogs.cs View......
  • 如何在EF Core中实现悲观锁
    问题描述在高流量场景下,绝对需要确保一次只有一个进程可以修改一块数据。假设你正在为一个极其受欢迎的音乐会构建售票系统。顾客们热切地抢购门票,最后几张票可能同时被售出。如果你不小心,多个顾客可能认为他们已经确保了最后的座位,导致超售!EntityFrameworkCore是一个好工具,但......
  • coredump时core文件生成
    要想生成core文件分两步:分配空间使用ulimit-a查看Linux资源分配情况,一般core后面的空间为0.可以使用ulimit-cunlimited设置为无限制大小,或使用ulimit-c100设置大小100Bytes修改路径默认路径很怪,一般需要修改到可执行文件的同一目录下,可以在sysctl.conf文件末尾添加一行......
  • Asp-Net-Core开发笔记:使用alpine镜像并加入健康检查
    前言使用docker部署AspNetCore应用已经是标配了,之前我一直使用mcr.microsoft.com/dotnet/aspnet:8.0这类镜像,简单粗暴,不过可以使用alpine进一步优化镜像大小。很多开源工具的docker都有健康检查,这次我顺便也给加上了。添加健康检查注册服务builder.Services.AddHea......
  • IIS 执行此操作时出错。 详细信息:web.config 错误,.net core项目
    一、IIS执行此操作时出错。详细信息:web.config错误,.netcore项目   运行报错错误信息提示的很明确:IISWebCore模块问题二、解析:IIS下报错,但是直接启动exe文件可以正常运行。 三、解决方案先安装IIS,然后安装Asp.netCore运行时。 更多:IIS10隐藏https......
  • c# .net core 将对应的语句转成dsl
    痛点:遇到一个问题,代码嵌套的es查询逻辑,太乱,太复杂。通过代码直观人工去转dsl发现根本不可能。后老看到调试模式能拿到dsl,方法如下https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/debug-mode.html使用debug模式,按文档的设置。设置完成之后,按文档https:......