Testing Incoming URL
If you need to test routes, you need to mock three classes from the MVC Framework: HttpRequestBase, HttpContextBase and HttpResponseBase(only for outgoing URL´s)
private HttpContextBase CreateHttpContext(string targetUrl = null, string httpMethod = "GET")
{
// create mock request
Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>();
// url you want to test through the property
mockRequest.Setup(m => m.AppRelativeCurrentExecutionFilePath).Returns(targetUrl);
mockRequest.Setup(m => m.HttpMethod).Returns(httpMethod);
// create mock response
Mock<HttpResponseBase> mockResponse = new Mock<HttpResponseBase>();
mockResponse.Setup(m => m.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s);
// create the mock context, using the request and response
Mock<HttpContextBase> mockContext = new Mock<HttpContextBase>();
mockContext.Setup(m => m.Request).Returns(mockRequest.Object);
mockContext.Setup(m => m.Response).Returns(mockResponse.Object);
// return the mock context object
return mockContext.Object;
}
then you need an additional helper method that let´s you specify the URL to test and the expected segment variables and an object for additional variables.
private void TestRouteMatch(string url, string controller, string action,
object routeProperties = null, string httpMethod = "GET")
{
// arrange
RouteCollection routes = new RouteCollection();
// loading the defined routes about the Route-Config
RouteConfig.RegisterRoutes(routes);
RouteData result = routes.GetRouteData(CreateHttpContext(url, httpMethod));
// assert
Assert.IsNotNull(result);
// here you can check your properties (controller, action, routeProperties) with the result
Assert.IsTrue(.....);
}
You don´t need to define your routes in the test methodes, because they were load directly using the RegisterRoutes method in the RouteConfig class.
The mechanism by wich inbound URL matching works.
GetRouteData(HttpContextBase httpContext)
referencesource.microsoft
The framework calls this method for each route table entry, until one of thems returns a non-null value.
You have to call the helper method as example in this way
[TestMethod]
public void TestIncomingRoutes() {
// check for the URL that is hoped for
TestRouteMatch("~/Home/Index", "Home", "Index");
}
the method check the URL you expecting as in the example above, call the Index action in the Home controller. You must prefix the URL with tilde (~) this is they way how the ASP.NET Framework presents the URL to the routing system.
In reference to the book Pro ASP.NET MVC 5 by Adam Freeman i can recommand it to every ASP.NET MVC developer!