ASP. net mvc Tip #13-Perform unit tests on custom routes

Source: Internet
Author: User
Tags xunit
ASP. net mvc Tip #13-Perform unit tests on custom routes

Address: http://weblogs.asp.net/stephenwalther/archive/2008/07/02/asp-net-mvc-tip-13-unit-test-your-custom-routes.aspx

Translation: Anders Liu

Abstract: In this Tip, Stephen Walther demonstrates how to create a unit test for custom routes in your ASP. net mvc application. Stephen Walther describes how to test whether a URL is mapped to the correct controller, controller operation, and operation parameters.

When creating ASP. net mvc applications, if you are loyal to test-driven development, you should perform unit tests on everything. Write unit tests first, and then code to perform tests. Repeated, repeated, repeated to vomit.

Routing is an important part of MVC applications. Routing determines how a URL is mapped to a specific controller and controller. Because routing is so important in MVC applications, you need to write unit tests for routing. In this Tip, I will show you how to write unit tests for routes by copying HTTP Context.

Create a route table

You can create a route for the MVC application in the Global. asax file. In other words, they are defined in the GlobalApplication class. Listing 1 contains the default Global. asax file.

Listing 1-Global. asax

<Br/> using System; <br/> using System. collections. generic; <br/> using System. linq; <br/> using System. web; <br/> using System. web. mvc; <br/> using System. web. routing; </p> <p> namespace DefaultOne <br/> {<br/> public class GlobalApplication: System. web. httpApplication <br/>{< br/> public static void RegisterRoutes (RouteCollection routes) <br/>{< br/> routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); </p> <p> routes. mapRoute (<br/> "Default", // Route name <br/> "{controller}/{action}/{id }", // URL with parameters <br/> new {controller = "Home", action = "Index", id = ""} // Parameter defaults <br/> ); </p> <p >}</p> <p> protected void Application_Start () <br/>{< br/> RegisterRoutes (RouteTable. routes); <br/>}< br/>

By default, a route includes the name, path, and default route. After a URL is obtained, the route maps different segments to specific controllers, controller operations, and parameters passed to the operation. For example:

  • /Customer/Details/23

    • Controller = Customer
    • Action = Details
    • Id = 23

The first segment in the URL is mapped to the Controller name, the second part is mapped to the Controller operation, and the last part is mapped to the parameter named Id.

The Default route includes the Default value. If no controller is specified, the Home controller is used. If no operation is specified, the Index operation is called. If no Id is specified, the first null string is passed. Therefore, the following URL is interpreted as follows:

  • /

    • Controller = Home
    • Action = Index
    • Id = ""

For many MVC applications, default routing is a frequently used one. However, you can also choose to create a custom route. For example, the Global. asax file in Listing 2 contains two custom routes.

Listing 2-Global. asax

<Br/> using System; <br/> using System. collections. generic; <br/> using System. linq; <br/> using System. web; <br/> using System. web. mvc; <br/> using System. web. routing; </p> <p> namespace Tip13 <br/> {<br/> public class GlobalApplication: System. web. httpApplication <br/>{< br/> public static void RegisterRoutes (RouteCollection routes) <br/>{< br/> routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); </p> <p> // Route for blog archive <br/> routes. mapRoute (<br/> "Archive", // Name <br/> "Archive/{entryDate}", // URL <br/> new {controller = "Blog ", action = "Details "}, // Defaults <br/> new {entryDate = @ "\ d {2}-\ d {2}-\ d {4}"} // Constraints <br/>); </p> <p> // Default route <br/> routes. mapRoute (<br/> "Default", // Name <br/> "{controller}/{action}/{id }", // URL <br/> new {controller = "Home", action = "Index", id = ""} // Defaults <br/> ); </p> <p> // Catch all route <br/> routes. mapRoute (<br/> "CatchIt", // Name <br/> "Product/{* values }", // URL <br/> new {controller = "Product", action = "Index"} // Defaults <br/> ); </p> <p >}</p> <p> protected void Application_Start () <br/>{< br/> RegisterRoutes (RouteTable. routes); <br/>}< br/>

In list 2, the modified Global. asax contains a new route named Archive, which is used to process requests for blog articles similar to the following:

  • /Archive/12-25-1966

The custom route maps the URL to the Controller named Blog and calls the Details () operation. The date is passed to the Details () operation as a parameter named entryDate.

The Global. asax file also defines a catchall route. The catchall route contains any number of segments. For example, the catchall route will match:

  • /Product/
  • /Product/a/B
  • /Product/a/B/c

And so on.

Perform unit tests on custom routes

How can I test a custom route? Before I saw an MVC unit test example from xUnit (http://www.codeplex.com/xUnit), I could not point out how to do such a unit test. To test custom routes, You need to copy the HTTP Context.

In the previous Tip, I introduced how to copy context objects when performing unit tests on ASP. NET internal objects such as session Status, form parameters, and user entities/roles. If you have not read this Blog, visit the following page:

  • Http://www.cnblogs.com/AndersLiu/archive/2008/07/26/asp-net-mvc-tip-12-faking-the-controller-context.html

After reading the xUnit example, I modified the imitation context object so that it can be used to perform unit tests on the route. The unit test in listing 3 demonstrates how to test the custom route contained in Global. asax in Listing 2.

Listing 3-RouteTest. cs

<Br/> using System; <br/> using System. web. routing; <br/> using Microsoft. visual Studio. testTools. unitTesting; <br/> using MvcFakes; <br/> using Tip13; </p> <p> namespace Tip13Tests. routes <br/> {<br/> [TestClass] <br/> public class RoutesTest <br/> {<br/> [TestMethod] <br/> public void TestDefaultRoute () <br/>{< br/> // Arrange <br/> var routes = new RouteCollection (); <br/> GlobalApplication. registerRo Utes (routes); </p> <p> // Act <br/> var context = new FakeHttpContext ("~ /"); <Br/> var routeData = routes. getRouteData (context); </p> <p> // Assert <br/> Assert. areEqual ("Home", routeData. values ["controller"], "Default controller is HomeController"); <br/> Assert. areEqual ("Index", routeData. values ["action"], "Default action is Index"); <br/> Assert. areEqual (String. empty, routeData. values ["id"], "Default Id is empty string"); <br/>}</p> <p> [TestMethod] <br/> public void TestGoodArchiveRoute () <br/>{< br/> // Arrange <br/> var routes = new RouteCollection (); <br/> GlobalApplication. registerRoutes (routes); </p> <p> // Act <br/> var context = new FakeHttpContext ("~ /Archive/12-25-1966 "); <br/> var routeData = routes. getRouteData (context); </p> <p> // Assert <br/> Assert. areEqual ("Blog", routeData. values ["controller"], "Controller is Blog"); <br/> Assert. areEqual ("Details", routeData. values ["action"], "Action is Details"); <br/> Assert. areEqual ("12-25-1966", routeData. values ["entryDate"], "EntryDate is date passed"); </p> <p >}</p> <p> [TestMethod] <br/> public voi D TestBadArchiveRoute () <br/>{< br/> // Arrange <br/> var routes = new RouteCollection (); <br/> GlobalApplication. registerRoutes (routes); </p> <p> // Act <br/> var context = new FakeHttpContext ("~ /Archive/something "); <br/> var routeData = routes. getRouteData (context); </p> <p> // Assert <br/> Assert. areNotEqual ("Blog", routeData. values ["controller"], "Controller is not Blog"); <br/>}</p> <p> [TestMethod] <br/> public void TestCatchAllRoute () <br/>{< br/> // Arrange <br/> var routes = new RouteCollection (); <br/> GlobalApplication. registerRoutes (routes); </p> <p> // Act <br/> var context = new FakeHttpContext ("~ /Product/a/B/c/d "); <br/> var routeData = routes. getRouteData (context); </p> <p> // Assert <br/> Assert. areEqual ("a/B/c/d", routeData. values ["values"], "Got catchall values"); <br/>}< br/>

This is a Visual Studio Test (MS Test) unit Test. Of course, you can also use different testing frameworks, such as NUnit or xUnit. The following is how this unit test works.

First, create a route set and pass it to the RegisterRoutes () method defined in the Global. asax file. The Global. asax file corresponds to a class named GlobalApplication.

Next, create an imitation HTTP Context that contains the URL to be tested. For example, in a test, URL ~ /Archive/12-25-1966 is passed to the constructor of the imitation HTTP Context object. The copied HTTP Context object is a modified version of the copied MVC object created in Tip #12. You can download the source code later in this article. The MvcFakes project contains these imitation objects.

Next, the GetRouteData () method is used in the imitation context and the route data is returned. Route data indicates the result of passing the URL to the application route table after explanation. In other words, the route data is obtained after comparing the URL with the route in the route table.

Finally, the test checks whether the route data contains the required values. In the first test, the Controller name, controller operation, and Id value were verified. According to this test, the empty URL ~ /It should be mapped to the Home controller and Index operation, and the Id value is String. Empty.

The second test checked for a similar ~ Whether requests such as/Archive/12-25-1966 are mapped to the Blog controller and Details operations, and an operation named entryDate is created.

The third test checked for a similar ~ Requests such as/Archive/something cannot be mapped to the Blog controller. Because the URL does not contain the appropriate entryDate, it cannot be processed by the Blog controller.

The last test proves that the catchall route works correctly. This test has checked ~ /Product/a/B/c/d is parsed to make the values parameter equal to a/B/c/d. In other words, it checks the catch-all part of the catchall controller.

Summary

In this Tip, I show you a simple method to test custom ASP. NET MVC routing. I recommend that you perform unit tests on the default route in the Global. asax file whenever you modify it.

Download the source code here: http://weblogs.asp.net/blogs/stephen enwalther/downloads/tip13/tip13.zip.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.