点击上方蓝字关注“汪宇杰博客”

导语

在 ASP.NET Core 里,如果你想单元测试 HttpContext.Features.Get<SomeType>(),这个技巧一定不要错过。

问题

我有个 Error 页面,需要取得异常的详细信息。我使用 HttpContext.Features.Get<IExceptionHandlerPathFeature>() 方法。

public void OnGet()

{

var requestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

if (exceptionFeature is not null)

{

// Get which route the exception occurred at

var routeWhereExceptionOccurred = exceptionFeature.Path;

// Get the exception that occurred

var exceptionThatOccurred = exceptionFeature.Error;

_logger.LogError($"Error: {routeWhereExceptionOccurred}, " +

$"client IP: {HttpContext.Connection.RemoteIpAddress}, " +

$"request id: {requestId}", exceptionThatOccurred);

}

RequestId = requestId;

}

现在,我需要单元测试这段代码。通常,在需要 HttpContext的 Page 或 Controller 中,我会使用 DefaultHttpContext 的实例。但我发现 HttpContext 上的 Features 属性是只读的。因此没有办法将 mock 好的对象赋值给它。

namespace Microsoft.AspNetCore.Http

{

public abstract class HttpContext

{

protected HttpContext();

//

// Summary:

//     Gets the collection of HTTP features provided by the server and middleware available

//     on this request.

public abstract IFeatureCollection Features { get; }

//  ...

}

}

解决办法

首先,像平常一样准备 mock。在我的案例里,我需要配置 IFeatureCollection.Get() 方法,返回我想要的对象。

var mockIFeatureCollection = _mockRepository.Create<IFeatureCollection>();

mockIFeatureCollection.Setup(p => p.Get<IExceptionHandlerPathFeature>())

.Returns(new ExceptionHandlerFeature

{

Path = "/996/icu",

Error = new("Too much fubao")

});

httpContextMock.Setup(p => p.Features).Returns(mockIFeatureCollection.Object);

下下来,为了给 HttpContext.Features 赋值,我们这次不能使用 DefaultHttpContext 了。我们需要创建 HttpContext 自己的 mock,并且配置 Features 属性返回刚才 mock 的 IFeatureCollection 对象。

var httpContextMock = _mockRepository.Create<HttpContext>();

httpContextMock.Setup(p => p.Features).Returns(mockIFeatureCollection.Object);

现在运行单元测试,我们可以看到正确的值已经输出了。

汪宇杰博客

Azure | .NET | 微软 MVP

无广告,不卖课,做纯粹的技术公众号

ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()相关推荐

  1. Asp.Net Core 单元测试正确姿势

    背景 ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,并且默认注入了很多服务,具体可以参考 官方文档, 相信只要使用过依赖注入框架的同学,都会对此有不同深入的理解,在此无需赘言. ...

  2. ASP.NET Core 单元测试:如何Mock Url.Page()

    点击上方蓝字关注"汪宇杰博客" 导语 在 ASP.NET Core 中,当你在 UrlHelperExtensions 类上使用扩展方法时,很难在单元测试中编写Mock.因为Moq ...

  3. 关于单元测试的思考--Asp.Net Core单元测试最佳实践

    https://www.cnblogs.com/yubaolee/p/DotNetCoreUnitTest.html 在我们码字过程中,单元测试是必不可少的.但在从业过程中,很多开发者却对单元测试望而 ...

  4. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    本系列文章从源码分析的角度来探索 ASP.NET Core 的运行原理,分为以下几个章节: ASP.NET Core 运行原理解剖[1]:Hosting ASP.NET Core 运行原理解剖[2]: ...

  5. ASP.NET Core自定义响应内容

    问题 在业务开发中,对Web API的返回格式有一定要求,需要是定制化的Json结构,用于前端统一处理: {Status : 0,Message: "",Info : xxx } ...

  6. 学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?

    ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 "通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流 ...

  7. 学习ASP.NET Core,你必须知道“中间件”是什么?中间件如何注册?请求处理管道是如何通过中间件构建的?

    ASP.NET Core 的请求处理管道由一个Server和一组有序排列的中间件构成,前者仅仅完成基本的请求监听.接收和响应的工作,请求接收之后和响应之前的所有工作都交给注册的中间件来完成.ASP.N ...

  8. ASP.NET Core管道深度剖析(3):管道是如何处理HTTP请求的?

    我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但是就具体的实现来说,由于其中涉及很多对象的交互,我想很少人能够地把它弄清楚.为了让读者 ...

  9. ASP.NET Core真实管道详解[1]

    ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 <ASP.NET Core管道深度剖析[共4篇]> 中围绕着一个经过极度简化的模拟 ...

最新文章

  1. 自动发布工具应该具备的11个标准特征
  2. 连接myeclipse和mysql数据库,MyEclipse与Mysql数据库的连接
  3. margin塌陷问题
  4. Powerdesigner 在线打开 不用安装客户端 访问pdm,ldm文件
  5. Vue单页面在ios10系统上出现白屏的bug
  6. 前端学习(2246)码云课程介绍
  7. springmvc的ModelAttribute注解
  8. 莒南机器人_莒南五小学子 在2020年世界FTF青少年无人机大赛中 荣获佳绩
  9. MySQL初始化安装部署
  10. Ubuntu下安装PHP的mongodb扩展操作命令
  11. geoda权重矩阵导入matlab,空间计量 用geoda创建空间权重矩阵
  12. 浏览器内置打开方正CEB是文件进行阅读
  13. hive_实现ip的十进制和点分十进制(xxx.xxx.xxx.xxx)之间的相互转换
  14. Spring Cloud Gateway⑤令牌桶算法
  15. 设计师们做UI设计和交互设计、界面设计等一般会去什么网站呢?
  16. 双目摄像机获取标定图片
  17. SFP光模块接口说明
  18. python识别字符串码置_python 字符串内置方法整理
  19. thx是什么意思_thx什么意思?
  20. QT pro文件和pri文件的区别

热门文章

  1. [music]Canon and Gigue in D major
  2. 统计nginx日志里访问次数最多的前十个IP
  3. 常用模块之 time,datetime,random,os,sys
  4. stm32 usmart使用
  5. retain、strong、weak、assign区别
  6. 高并发高可靠性系统思考1
  7. 洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)
  8. 【Android】RxJava的使用(四)线程控制 —— Scheduler
  9. Unbuntu 自动重启MySQL
  10. Linux挂载命令mount详解