ASP.NET Core 单元测试:如何Mock Url.Page()
点击上方蓝字关注“汪宇杰博客”
导语
在 ASP.NET Core 中,当你在 UrlHelperExtensions 类上使用扩展方法时,很难在单元测试中编写Mock。因为Moq框架不支持模拟扩展方法。
问题
例如,我的博客代码中使用了 Url.Page() 方法:
var callbackUrl = Url.Page("/Index", null, null, Request.Scheme);
但是单元测试中,像这样 Mock 就会爆:
var mockUrlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);mockUrlHelper.Setup(x => x.Page("/Index", null, null, It.IsAny<string>())).Returns("callbackUrl").Verifiable();
爆炸现场
System.NotSupportedException : Unsupported expression: x => x.Page("/Index", null, null, It.IsAny<string>()) Extension methods (here: UrlHelperExtensions.Page) may not be used in setup / verification expressions.
解决方法
我们需要 Mock 这个拓展方法调用的底层方法。在本案例中,底层方法是
Microsoft.AspNetCore.Mvc.IUrlHelper.RouteUrl(UrlRouteContext routeContext)
我是怎么知道的呢?很简单,.NET 都已经开源多少年了,直接看一眼源代码就能知道微软如何单元测试 UrlHelperExtensions。
https://source.dot.net/
从微软的代码里复制两个助手方法
private Mock<IUrlHelper> CreateMockUrlHelper(ActionContext context = null)
{
context ??= GetActionContextForPage("/Page");
var urlHelper = _mockRepository.Create<IUrlHelper>();
urlHelper.SetupGet(h => h.ActionContext)
.Returns(context);
return urlHelper;
}
private static ActionContext GetActionContextForPage(string page)
{
return new()
{
ActionDescriptor = new()
{
RouteValues = new Dictionary<string, string>
{
{ "page", page },
}
},
RouteData = new()
{
Values =
{
[ "page" ] = page
}
}
};
}
修改我们的单元测试
var mockUrlHelper = CreateMockUrlHelper();mockUrlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>())).Returns("callbackUrl");
现在单元测试就能顺利跑过了!
完整的单元测试代码见下方供参考:
[Test]
public async Task SignOutAAD()
{
_mockOptions.Setup(m => m.Value).Returns(new AuthenticationSettings
{
Provider = AuthenticationProvider.AzureAD
});
var mockUrlHelper = CreateMockUrlHelper();
mockUrlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
.Returns("callbackUrl");
var ctx = new DefaultHttpContext();
var ctl = CreateAuthController();
ctl.ControllerContext = new() { HttpContext = ctx };
ctl.Url = mockUrlHelper.Object;
var result = await ctl.SignOut();
Assert.IsInstanceOf(typeof(SignOutResult), result);
}
汪宇杰博客
Azure | .NET | 微软 MVP
无广告,不卖课,做纯粹的技术公众号
ASP.NET Core 单元测试:如何Mock Url.Page()相关推荐
- Asp.Net Core 单元测试正确姿势
背景 ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,并且默认注入了很多服务,具体可以参考 官方文档, 相信只要使用过依赖注入框架的同学,都会对此有不同深入的理解,在此无需赘言. ...
- asp.net core设置默认起始页Default Page和重定向
为什么80%的码农都做不了架构师?>>> 用Asp.Net Core的网站Deploy至IIS,因此找了下,发现两种方法: 添加引用 using System.Threadin ...
- ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()
点击上方蓝字关注"汪宇杰博客" 导语 在 ASP.NET Core 里,如果你想单元测试 HttpContext.Features.Get<SomeType>(),这个 ...
- 关于单元测试的思考--Asp.Net Core单元测试最佳实践
https://www.cnblogs.com/yubaolee/p/DotNetCoreUnitTest.html 在我们码字过程中,单元测试是必不可少的.但在从业过程中,很多开发者却对单元测试望而 ...
- ASP.NET Core URL Rewrite中间件
URL重写是基于一个或多个预置规则修改请求URL的行为.URL重写在资源位置和访问地址之间创建了一种抽象,这样二者之间就减少了紧密的联系.URL重写有多种适用的场景: 临时或永久移动或替换服务器资源, ...
- ASP.NET Core的Kestrel服务器
原文地址----Kestrel server for ASP.NET Core By Tom Dykstra, Chris Ross, and Stephen Halter Kestrel是一个基于l ...
- ASP.NET Core 管道再探
几乎任何服务器端处理环境都有自己的直通组件管道,用于检查.重路由或修改传入请求和传出响应.经典 ASP.NET 围绕 HTTP 模块理念进行排列,而 ASP.NET Core 采用基于中间件组件的更现 ...
- ASP.NET Core MVC+EF Core从开发到部署
笔记本电脑装了双系统(Windows 10和Ubuntu16.04)快半年了,平时有时间就喜欢切换到Ubuntu系统下耍耍Linux,熟悉熟悉Linux命令.Shell脚本以及Linux下的各种应用的 ...
- ASP.NET Core 对Controller进行单元测试
单元测试对我们的代码质量非常重要.很多同学都会对业务逻辑或者工具方法写测试用例,但是往往忽略了对Controller层写单元测试.我所在的公司没见过一个对Controller写过测试的.今天来演示下如 ...
最新文章
- Cell子刊:微生物组学研究的突破与瓶颈
- 3.对角线遍历(LeetCode第498题)
- rhel 8.2不识别unicode_基于tensorflow 实现端到端的OCR:二代身份证号识别
- Magento微信支付接口开发小记
- 手把手教你逼走员工的23种套路,大写的服!
- 深度卷积神经网络的高级主题
- 计算机电脑用户名,如何改计算机用户名(administrator)
- jq富文本_jQuery富文本编辑器Notebook
- 如何实现thead固定不动,tbody出现垂直滚动条
- 计算机关机界面设置在哪里,电脑怎么设置关机画面
- Windows快捷键小记
- 重拾Java基础知识:设计模式
- Oracle创建数据库连接——DATABASE LINKS
- 怎么制作区域分布图,怎么做网点分布图
- 损失惨重!数据中心失火,360万个网站下线,Rust游戏25台服务器数据永久丢失...
- 使用node-red通过MQTT传送数据
- java wmf格式图片转png
- 记HP 12c的一个坑
- 入门Python必备100道练习题
- 我的python入门心得