当前位置: 首页 > 编程语言 > C#

测试请求的URL是否在Route表中共享

时间:2023-04-10 20:30:03 C#

测试请求的URL是否在Route表中我想测试一个URL是否是Global.asax定义的路由的一部分。这就是我所拥有的:varTheRequest=HttpContext.Current.Request.Url.AbsolutePath.ToString();varTheRoutes=System.Web.Routing.RouteTable.Routes;foreach(varTheRouteinTheRoutes){if(TheRequest==TheRoute.Url)//这里有问题{RequestIsInRoutes=true;}}问题是我无法从路由中提取URL。我需要改变什么?问题是我无法从路由中提取URL。我不同意。问题是您想从路由表中提取URL并在外部进行比较。此外,不清楚您希望通过这样做获得什么。路由将传入请求与业务逻辑进行比较,以确定它是否匹配。这就是路线的目的。将匹配逻辑移到路由之外不是有效测试,因为您没有测试路由实现的业务逻辑。更不用说,假设路由只能匹配URL而不能匹配请求中的任何其他内容(例如表单post值或cookie),这有点推测。虽然内置路由功能仅匹配URL,但没有什么能阻止您制定符合其他条件的约束或自定义路由。因此,简而言之,您需要在路由中为您的业务逻辑编写单元测试。在路由配置之外发生的任何逻辑都应该单独进行单元测试。BradWilson有一篇很棒(虽然有点旧)的文章演示了如何对您的路线进行单元测试。我已经更新了代码以使用MVC5-这是一个使用下面代码的工作演示。使用Microsoft.VisualStudio.TestTools.UnitTesting的IncomingRouteTests.cs;使用MvcRouteTesting;使用System.Web.Mvc;使用System.Web.Routing;[TestClass]publicclassIncomingRouteTests{[TestMethod]publicvoidRouteWithControllerNoActionNoId(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/controller1");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//执行RouteDatarouteData=routes.GetRouteData(context);//断言Assert.IsNotNull(routeData);Assert.AreEqual("controller1",routeData.Values["controller"]);Assert.AreEqual("Index",routeData.Values["action"]);Assert.AreEqual(UrlParameter.Optional,routeData.Values["id"]);}[TestMethod]publicvoidRouteWithControllerWithActionNoId(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/controller1/action2");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//执行RouteDatarouteData=routes.GetRouteData(上下文);//断言Assert.IsNotNull(routeData);Assert.AreEqual("controller1",routeData.Values["controller"]);Assert.AreEqual("action2",routeData.Values["action"]);Assert.AreEqual(UrlParameter.Optional,routeData.Values["id"]);}[TestMethod]publicvoidRouteWithControllerWithActionWithId(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/controller1/action2/id3");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//执行RouteDatarouteData=routes.GetRouteData(context);//断言Assert.IsNotNull(routeData);Assert.AreEqual("controller1",routeData.Values["controller"]);Assert.AreEqual("action2",routeData.Values["action"]);Assert.AreEqual("id3",routeData.Values["id"]);}[TestMethod]publicvoidRouteWithTooManySegments(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/a/b/c/d");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//ActRouteDatarouteData=routes.GetRouteData(context);//断言Assert.IsNull(routeData);}[TestMethod]publicvoidRouteForEmbeddedResource(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/foo.axd/bar/baz/biff");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//执行RouteDatarouteData=routes.GetRouteData(context);//断言Assert.IsNotNull(routeData);Assert.IsInstanceOfType(routeData.RouteHandler,typeof(StopRoutingHandler));}}OutgoingRouteTests.cs使用Microsoft.VisualStudio.TestTools.UnitTesting;使用MvcRouteTesting;使用System.Web;使用System.Web.Mvc;使用System.Web.Routing;[TestClass]公共类OutgoingRouteTests{[TestMethod]publicvoidActionWithAmbientControllerSpecificAction(){UrlHelperhelper=GetUrlHelper();字符串url=helper.Action("动作");Assert.AreEqual("/defaultcontroller/action",url);}[测试方法]publicvoidActionWithSpecificControllerAndAction(){UrlHelper助手=GetUrlHelper();stringurl=helper.Action("action","controller");Assert.AreEqual("/controller/action",url);}[TestMethod]publicvoidActionWithSpecificControllerActionAndId(){UrlHelperhelper=GetUrlHelper();stringurl=helper.Action("action","controller",new{id=42});Assert.AreEqual("/controller/action/42",url);}[TestMethod]publicvoidRouteUrlWithAmbientValues(){UrlHelperhelper=GetUrlHelper();字符串url=helper.RouteUrl(new{});Assert.AreEqual("/defaultcontroller/defaultaction",url);}[TestMethod]publicvoidRouteUrlWithAmbientValuesInSubApplication(){UrlHelperhelper=GetUrlHelper(appPath:"/subapp");字符串url=helper.RouteUrl(new{});Assert.AreEqual("/subapp/defaultcontroller/defaultaction",url);}[TestMethod]publicvoidRouteUrlWithNewValuesOverridesAmbientValues(){UrlHelperhelper=GetUrlHelper();stringurl=helper.RouteUrl(new{controller="controller",action=“行动”});Assert.AreEqual("/controller/action",url);}staticUrlHelperGetUrlHelper(stringappPath="/",RouteCollectionroutes=null){if(routes==null){routes=newRouteCollection();RouteConfig.RegisterRoutes(路线);}HttpContextBasehttpContext=newStubHttpContextForRouting(appPath);RouteDatarouteData=newRouteData();routeData.Values.Add("控制器","默认控制器");routeData.Values.Add("action","defaultaction");RequestContextrequestContext=newRequestContext(httpContext,routeData);UrlHelperhelper=newUrlHelper(requestContext,routes);返回帮手;Stubs.cs使用系统;使用System.Collections.Specialized;使用System.Web;公共类StubHttpContextForRouting:HttpContextBase{StubHttpRequestForRouting_request;StubHttpResponseForRouting_response;publicStubHttpContextForRouting(stringappPath="/",stringrequestUrl="~/"){_request=newStubHttpRequestForRouting(appPath,request网址);_response=newStubHttpResponseForRouting();}publicoverrideHttpRequestBaseRequest{get{return_request;}}publicoverrideHttpResponseBaseResponse{get{return_response;}}publicoverrideobjectGetService(TypeserviceType){returnnull;}}公共类StubHttpRequestForRouting:HttpRequestBase{string_appPath;字符串_requestUrl;publicStubHttpRequestForRouting(stringappPath,stringrequestUrl){_appPath=appPath;_requestUrl=requestUrl;}publicoverridestringApplicationPath{get{return_appPath;}}publicoverridestringAppRelativeCurrentExecutionFilePath{get{return_requestUrl;}}publicoverridestringPathInfo{get{return"";}}publicoverrideNameValueCollectionServerVariables{get{returnnewNameValueCollection();}}}publicclassStubHttpResponseForRouting:HttpResponseBase{publicoverridestringApplyAppPathModifier(stringvirtualPath){returnvirtualPath;}}有了这个,回到你原来的问题如何确定URL是否在路由表中?这个问题有点假设。正如其他人指出的那样,路由表不包含URL,它包含业务逻辑。更正确的表述问题的方式是:如何确定传入URL是否与路由表中的任何路由匹配?那么你就在路上了。为此,您需要在路由集合中实现GetRouteData业务逻辑。这将在每个路由上执行GetRouteData方法,直到它们中的第一个返回RouteData对象而不是null。如果它们都没有返回RouteData对象(即所有路由都返回null),则意味着没有路由与请求匹配。换句话说,GetRouteData的空结果意味着没有路由匹配请求。RouteData对象表示要匹配哪个路由,并提供必要的路由数据(controller、action等)使MVC匹配action方法。所以,要简单地检查一个URL是否匹配一个路由,你只需要判断操作的结果是否为null即可。[TestMethod]publicvoidEnsureHomeAboutMatches(){//安排varcontext=newStubHttpContextForRouting(requestUrl:"~/home/about");varroutes=newRouteCollection();RouteConfig.RegisterRoutes(路线);//执行RouteDatarouteData=routes.GetRouteData(context);//断言Assert.IsNotNull(routeData);另请注意,生成路由是与匹配传入路由不同的任务。您可以从路由生成传出URL,但它使用与匹配传入路由完全不同的一组业务逻辑。这个传出URL逻辑可以(并且应该)与传入URL逻辑分开进行单元测试,如上所示。不知道这是不是你想要的路由,如果是的话,你可以从当前请求中获取:varroute=HttpContext.Current.Request.RequestContext.RouteData.Route;您可以尝试根据路由表检查当前上下文varcontextBase=HttpContext.Current.Request.RequestContext.HttpContext;vardata=RouteTable.Routes.GetRouteData(contextBase);if(data!=null){//Routeexists}以上述作为创建服务的基础publicinterfaceIRouteInspector{boolRequestIsInRoutes();}公共接口IHttpContextAccessor{HttpContextBaseHttpContext{get;}}publicinterfaceIRouteTable{RouteCollectionRoutes{get;}}publicclassRouteInspector:IRouteInspector{privateIRouteTablerouteTable;私有IHttpContextAccessorcontextBase;publicRouteInspector(IRouteTablerouteTable,IHttpContextAccessorcontextBase){this.routeTable=routeTable;this.contextBase=contextBase;}publicboolRequestIsInRoutes(){if(routeTable.Routes.GetRouteData(contextBase.HttpContext)!=null){//路由存在returntrue;}返回假;这里是展示它是如何使用的测试类。[TestClass]publicclassRouteTableUnitTests:ControllerUnitTests{[TestMethod]publicvoidShould_Get_Request_From_Route_Table(){//安排varcontextBase=newMock();contextBase.Setup(m=>m.HttpContext).Returns(HttpContext.Current.Request.RequestContext.HttpContext);varrouteTable=newMock();routeTable.Setup(m=>m.Routes).Returns(RouteTable.Routes);varsut=newRouteInspector(routeTable.Object,contextBase.Object);//Actvaractual=sut.RequestIsInRoutes();//断言Assert.IsTrue(actual);有重构和改进的空间,但这是一个开始。这就是我最终做的事情:stringTheRequest=HttpContext.Current.Request.Url.AbsolutePath.ToString();foreach(RouterinSystem.Web.Routing.RouteTable.Routes){if(("/"+r.Url)==TheRequest){//请求在路由中}}这是hacky但它有3行.以上就是C#学习教程:测试请求的URL是否在Route表中共享。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: