引言

在上一章节我们实战了在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

使用 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,提高代码质量和开发效率。

欢迎关注笔者公众号一起学习交流,获取更多有用的知识~

精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性的更多相关文章

  1. ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露

    一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...

  2. List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac

    List多个字段标识过滤 class Program{  public static void Main(string[] args) { List<T> list = new List& ...

  3. ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx

    一.前言 在之前的文章(ASP.NET Core 实战:Linux 小白的 .NET Core 部署之路)中,我介绍了如何在 Linux 环境中安装 .NET Core SDK / .NET Core ...

  4. ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法

    一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实现对于数据库的快速访问,后来,ORM(Object Relatio ...

  5. ASP.NET Core开发者指南

    ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“ ...

  6. ASP.NET Core开发者指南(转发)

    ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.& ...

  7. ASP.NET Core开发者指南(2022版路线图)

    ASP.NET Core开发者指南 2022年 ASP.NET Core 开发者指南: 在下面,您可以看到一个图,说明可以采用的路径以及要成为ASP.NET Core开发人员所想要学习的库.我将此图作 ...

  8. ASP.NET Core 实战:将 .NET Core 2.0 项目升级到 .NET Core 2.1

    一.前言  最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知 ...

  9. 新的ASP.NET Core 迁移指南

    最近在微信里做了一个调查: Web Forms应用程序升级到.NET 6, 收到550份调查,调查还在继续,欢迎参与调查.可以访问链接:https://wj.qq.com/s2/9822949/ac3 ...

  10. ASP.NET Core 实战:构建带有版本控制的 API 接口

    一.前言 在上一篇的文章中,主要是搭建了我们的开发环境,同时创建了我们的项目模板框架.在整个前后端分离的项目中,后端的 API 接口至关重要,它是前端与后端之间进行沟通的媒介,如何构建一个 “好用” ...

随机推荐

  1. nowrap - table td 列 宽度 不被挤 - 大表格制作

    nowrap - table td 列 宽度 不被挤 - 大表格制作 表格前几列 设置完宽度,会被右侧动态数据挤没有宽度,加上nowrap,就保证宽度了

  2. Kotlin学习快速入门(8)—— 委托

    原文地址:Kotlin学习快速入门(8)-- 属性委托 - Stars-One的杂货小窝 委托其实是一种设计模式,但Kotlin把此特性编写进了语法中,可以方便开发者快速使用 委托对应的关键字是by ...

  3. day01-1-需求分析和项目设计

    满汉楼01 1.需求分析 满汉楼项目说明 因为javaGUI不是学习的重点,这里将继续使用控制台界面来代替界面和事件处理 完成的功能: 登录 订座 点餐 结账 查看账单等功能 在实际项目中,独立完成项 ...

  4. java线程池知识整理

    参考,欢迎点击原文:https://www.jianshu.com/p/246021d04310(java多线程那点事) https://blog.csdn.net/fanrenxiang/artic ...

  5. MyEclipse之各个版本的区别

    跟Eclipse一样,MyEclipse的各个版本也是有区别的,他们所集成的插件是不同的. 从插件数量和功能的强大程度上讲:Blue>Professional>Standard MyEcl ...

  6. Spring Boot学习日记4

    学会pom.xml 分析 打开pom.xml,看看Spring Boot项目的依赖: <?xml version="1.0" encoding="UTF-8&quo ...

  7. 用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.组件设计 组件就是把图形.非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式 现在有一个场景,点击新增与编辑都弹框出来进行 ...

  8. 利用Python 去重聚合Excel数据并对比两份数据的差异

    问题背景 在数据处理过程中,常常需要将多个数据表进行合并,并进行比对,以便找出数据的差异和共同之处.本文将介绍如何使用 Pandas 库对两个 Excel 数据表进行合并与比对,并将结果输出到新的 E ...

  9. C# 调用C++DLL时释放非托管内存

    方法一 改变非托管内存的分配方法,将其修改成采用COM的内存分配方法CoTaskMemAlloc来分配内存.这样封送拆收器在释放非托管内存时,就能自动调用COM的内存释放方法CoTaskMemFree ...

  10. Spring Cloud相关组件说明

    1.Spring Cloud版本 现有Spring Cloud有两代实现,分为Spring Cloud Netflix和Spring Cloud Alibaba,由于SpringCloud Netfl ...