精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性
引言
在上一章节我们实战了在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 的任何属性,从而精确控制请求的各个方面。相比于使用 HttpClient,SendAsync 通常更快,因为它绕过了网络层。
集成测试:这是测试整个请求处理管道(包括所有中间件)的好方法。
然而,它也有一些限制:
局限性:
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项目中测试中间件的方法和技巧。通过使用TestServer和HttpContext发送请求,我们可以模拟整个应用程序的运行环境,从而进行集成测试和端到端测试。同时,我们也介绍了如何添加请求路由来模拟不同的场景,并对中间件的行为进行验证。
通过测试中间件,我们可以确保其在处理请求时的行为符合预期,提高应用程序的稳定性和可靠性。测试不仅可以帮助发现潜在的问题,还可以在开发过程中及早发现和解决 bug,提高代码质量和开发效率。
欢迎关注笔者公众号一起学习交流,获取更多有用的知识~

精通中间件测试:Asp.Net Core实战指南,提升应用稳定性和可靠性的更多相关文章
- ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露
一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...
- 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& ...
- ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx
一.前言 在之前的文章(ASP.NET Core 实战:Linux 小白的 .NET Core 部署之路)中,我介绍了如何在 Linux 环境中安装 .NET Core SDK / .NET Core ...
- ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法
一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实现对于数据库的快速访问,后来,ORM(Object Relatio ...
- ASP.NET Core开发者指南
ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“ ...
- ASP.NET Core开发者指南(转发)
ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.& ...
- ASP.NET Core开发者指南(2022版路线图)
ASP.NET Core开发者指南 2022年 ASP.NET Core 开发者指南: 在下面,您可以看到一个图,说明可以采用的路径以及要成为ASP.NET Core开发人员所想要学习的库.我将此图作 ...
- ASP.NET Core 实战:将 .NET Core 2.0 项目升级到 .NET Core 2.1
一.前言 最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知 ...
- 新的ASP.NET Core 迁移指南
最近在微信里做了一个调查: Web Forms应用程序升级到.NET 6, 收到550份调查,调查还在继续,欢迎参与调查.可以访问链接:https://wj.qq.com/s2/9822949/ac3 ...
- ASP.NET Core 实战:构建带有版本控制的 API 接口
一.前言 在上一篇的文章中,主要是搭建了我们的开发环境,同时创建了我们的项目模板框架.在整个前后端分离的项目中,后端的 API 接口至关重要,它是前端与后端之间进行沟通的媒介,如何构建一个 “好用” ...
随机推荐
- $event - vue中默认参数的显示 - @on-change="func($event, code)" - 基础知识
@on-change="checkAllOnChangeHandle($event,scItem.code)"
- 将谷歌chrome浏览器主题变黑的方法
两个步骤: 第一: 桌面找到google chrome图标右键->属性,在后面加上: --force-dark-mode (注意有空格) 第二: 1.浏览器地址输入chrome://flags/ ...
- webpack 项目接入Vite的通用方案介绍(下)
愿景 希望通过此系列文章,能给读者提供一个存/增量项目接入Vite的点子,起抛砖引玉的作用,减少这方面能力的建设成本 在阐述过程中同时也会逐渐完善webpack-vite-serve这个工具 读者可直 ...
- RecyclerView瀑布流优化方案探讨
目录介绍 01.规则瀑布流实现 02.不规则瀑布流实现 2.1 实现方式 2.2 遇到问题 03.瀑布流上拉加载 04.给瀑布流设置分割线 05.自定义Manager崩溃 06.如何避免刷新抖动 07 ...
- 02.Android之IPC机制问题
目录介绍 2.0.0.1 什么是Binder?为什么要使用Binder?Binder中是如何进行线程管理的?总结binder讲的是什么? 2.0.0.2 Android中进程和线程的关系?什么是IPC ...
- 浅析三维模型3DTile格式轻量化处理常见问题与处理措施
浅析三维模型3DTile格式轻量化处理常见问题与处理措施 三维模型3DTile格式的轻量化处理是大规模三维地理空间数据可视化的关键环节,但在实际操作过程中,往往会遇到一些问题.下面我们来看一下这些常见 ...
- 记录--Vue3 + Fabricjs 定制国庆专属头像
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 生在国旗下,长在春风里!国庆将至,采黎为大家带来 定制头像2.0(国庆头像),让我们用代码的形式为祖国庆生!欢迎大家点赞收藏加关注哦 前言 ...
- 记录转载:uni-app 请求 uni.request封装使用
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 对uni.request的一些共同参数进行简单的封装,减少重复性数据请求代码.方便全局调用. 先在目录下创建 utils 和 common ...
- 记录--Vue开发历程---音乐播放器
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.audio标签的使用 1.Audio 对象属性 2.对象方法 二.效果 效果如下: 三.代码 代码如下: MusicPlayer.vu ...
- Eagle+微力同步实现素材资源协同共享
在设计团队中,会有一些通用,标准的素材资料或者项目参考方案.这些资料当多人,多台电脑,多地电脑都需要时,就会有素材共享,素材统一管理的需求. Eagle共享数据能够使用的几种方法 1.将需要共享的素材 ...