当前位置: 首页 > 科技观察

ASP.NETCoreUnitTesting-HowtoMockUrl.Page()

时间:2023-03-17 10:11:49 科技观察

本文转载自微信公众号《王宇杰博客》,作者王宇杰。转载本文请联系王玉洁博客公众号。在ASP.NETCore中,当您在UrlHelperExtensions类上使用扩展方法时,很难在单元测试中编写模拟。因为Moq框架不支持模拟扩展方法。问题例如我的博客代码中使用了Url.Page()方法:varcallbackUrl=Url.Page("/Index",null,null,Request.Scheme);但是在单元测试中,像这样的Mock会爆炸:())).Returns("callbackUrl").Verifiable();爆炸场景System.NotSupportedException:Unsupportedexpression:x=>x。Page("/Index",null,null,It.IsAny())扩展方法(此处:UrlHelperExtensions.Page)不得在设置/验证表达式中使用。解决方案我们需要Mock扩展方法调用的底层方法。在这种情况下,底层方法是Microsoft.AspNetCore.Mvc.IUrlHelper.RouteUrl(UrlRouteContextrouteContext)我怎么知道?这很简单。.NET已经开源多??年。看看源码就知道微软是如何单元测试UrlHelperExtensions的。https://source.dot.net/从微软的代码中复制两个helper方法;urlHelper.SetupGet(h=>h.ActionContext).Returns(context);returnurlHelper;}privatestaticActionContextGetActionContextForPage(stringpage){returnnew(){ActionDescriptor=new(){RouteValues=newDictionary{{"page",page},}},RouteData=new(){Values={["page"]=page}}};}修改我们的单元测试varmockUrlHelper=CreateMockUrlHelper();mockUrlHelper.Setup(h=>h.RouteUrl(It.IsAny())).Returns("callbackUrl");现在单元测试可以顺利运行了!完整的单元测试代码如下,供参考:(h=>h.RouteUrl(It.IsAny())).Returns("callbackUrl");varctx=newDefaultHttpContext();varctl=CreateAuthController();ctl.ControllerContext=new(){HttpContext=ctx};ctl.Url=mockUrlHelper.Object;varresult=awaitctl.SignOut();Assert.IsInstanceOf(类型(SignOutResult),结果);}