翼度科技»论坛 编程开发 .net 查看内容

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

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
引言

在上一章节我们实战了在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
  1. PM> NuGet\Install-Package Microsoft.AspNetCore.TestHost -Version 8.0.4
复制代码
既然我们是要测试中间件 那首先得先在我们的Sample.Api中创建一个中间件
定义MyMiddleware中间件
  1. public class MyMiddleware(RequestDelegate next)
  2. {
  3.     public async Task InvokeAsync(HttpContext context)
  4.     {
  5.         // 在请求处理前执行的逻辑
  6.         context.Response.ContentType = "text/plain";
  7.         context.Response.Headers.TryAdd("X-Custom-Header", "CustomValue");
  8.         await context.Response.WriteAsync("Test My Middleware");
  9.         // 调用下一个中间件
  10.         await next(context);
  11.         // 在请求处理后执行的逻辑
  12.         await context.Response.WriteAsync("Middleware Test Completed");
  13.     }
  14. }
复制代码
定义测试类
  1.         // Arrange
  2.         using var host = await new HostBuilder()
  3.             .ConfigureWebHost(webBuilder =>
  4.             {
  5.                 webBuilder
  6.                     .UseTestServer()
  7.                     .ConfigureServices(services =>
  8.                     {
  9.                         // 在这里可以注入服务
  10.                     })
  11.                     .Configure(app =>
  12.                     {
  13.                         app.UseMiddleware<MyMiddleware>();
  14.                     });
  15.             })
  16.             .StartAsync();
  17.         // Act
  18.         var response = await host.GetTestClient().GetAsync("/");
  19.         // Assert
  20.         response.EnsureSuccessStatusCode(); // 确保请求成功
  21.         var responseContent = await response.Content.ReadAsStringAsync();
  22.         Assert.Contains("Test My Middleware", responseContent);
  23.         Assert.Contains("Middleware Test Completed", responseContent);
复制代码
Run Test

使用 HttpContext 发送请求

可以使用 TestServer 来设置测试环境,并创建一个模拟的 HttpContext对象来代表一个请求
  1.     [Fact]
  2.     public async Task TestMiddleware_ExpectedResponse()
  3.     {
  4.         using var host = await new HostBuilder()
  5.             .ConfigureWebHost(webBuilder =>
  6.             {
  7.                 webBuilder
  8.                     .UseTestServer()
  9.                     .ConfigureServices(services =>
  10.                     {
  11.                     })
  12.                     .Configure(app =>
  13.                     {
  14.                         app.UseMiddleware<MyMiddleware>();
  15.                     });
  16.             })
  17.             .StartAsync();
  18.         var server = host.GetTestServer();
  19.         server.BaseAddress = new Uri("http://localhost");
  20.         var context = await server.SendAsync(c =>
  21.         {
  22.             c.Request.Method = HttpMethods.Get;
  23.             c.Request.Path = "/";
  24.             c.Request.Host = new HostString("localhost");
  25.             c.Request.Scheme = "http";
  26.         });
  27.         //act
  28.         Assert.True(context.RequestAborted.CanBeCanceled);
  29.         Assert.Equal(HttpProtocol.Http11, context.Request.Protocol);
  30.         // 验证响应
  31.         Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
  32.         var customHeader = context.Response.Headers["X-Custom-Header"].ToString();
  33.         Assert.Equal("CustomValue", customHeader);
  34.     }
复制代码
使用 SendAsync 的好处包括:
通过设置 HttpContext 的任何属性,从而精确控制请求的各个方面。相比于使用 HttpClient,SendAsync 通常更快,因为它绕过了网络层。
集成测试:这是测试整个请求处理管道(包括所有中间件)的好方法。
然而,它也有一些限制:
局限性
SendAsync 主要用于集成测试,而不是单元测试。它测试的是整个请求处理流程,而不是单个组件。
模拟限制:虽然你可以设置 HttpContext 的许多属性来模拟请求,但某些方面(如用户认证状态或外部依赖项)可能难以完全模拟。
添加请求路由

这个比较好理解,就是在TestServer中添加路由的功能和Asp.Net Core中添加路由基本一致
  1.     [Fact]
  2.     public async Task TestWithEndpoint_ExpectedResponse()
  3.     {
  4.         using var host = await new HostBuilder()
  5.             .ConfigureWebHost(webBuilder =>
  6.             {
  7.                 webBuilder
  8.                     .UseTestServer()
  9.                     .ConfigureServices(services =>
  10.                     {
  11.                         services.AddRouting();
  12.                     })
  13.                     .Configure(app =>
  14.                     {
  15.                         app.UseRouting();
  16.                         //app.UseMiddleware<MyMiddleware>();
  17.                         app.UseEndpoints(endpoints =>
  18.                         {
  19.                             endpoints.MapGet("/hello", () =>
  20.                                 TypedResults.Text("Hello Tests"));
  21.                         });
  22.                     });
  23.             })
  24.             .StartAsync();
  25.         var client = host.GetTestClient();
  26.         var response = await client.GetAsync("/hello");
  27.         Assert.True(response.IsSuccessStatusCode);
  28.         var responseBody = await response.Content.ReadAsStringAsync();
  29.         Assert.Equal("Hello Tests", responseBody);
  30.     }
复制代码
在测试场景中,添加请求路由的好处主要体现在以下几个方面:

  • 模拟真实环境:
    通过添加请求路由,你可以模拟出与真实生产环境相似的请求处理流程。这使得测试更加接近实际使用情况,从而提高了测试的可靠性和有效性。
  • 控制测试的粒度:
    你可以针对特定的路由进行精确测试,确保每个路由都能正确响应并返回预期的结果。这有助于发现潜在的路由错误或逻辑问题,提高了测试的精度。
  • 隔离测试:
    在测试过程中,你可以通过配置路由来隔离特定的功能或组件,从而避免其他部分的干扰。这种隔离测试有助于更准确地定位问题,提高了测试的效率。
  • 模拟异常场景:
    通过配置路由,你可以模拟各种异常场景,如路由不存在、参数错误等。这有助于测试应用程序在异常情况下的响应和处理能力,提高了应用程序的健壮性。
  • 自动化测试:
    在自动化测试框架中,添加请求路由可以使得测试用例更加易于编写和执行。通过发送请求到特定的路由并验证响应,你可以自动化地检查应用程序的功能和性能。
最后

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

通过测试中间件,我们可以确保其在处理请求时的行为符合预期,提高应用程序的稳定性和可靠性。测试不仅可以帮助发现潜在的问题,还可以在开发过程中及早发现和解决 bug,提高代码质量和开发效率。
<em>
来源:https://www.cnblogs.com/ruipeng/p/18149582
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
来自手机

举报 回复 使用道具