Simple Solution to using httpcontext in unit test of C #

Source: Internet
Author: User
Tags reflector

Scenario: A. Net HTTP module was recently tested, which is used for URL rewriting. At the beginning, the progress was quite smooth, because the method parameters in the module were basically strings. Later, the module was restructured and all the parameters were changed to httpcontext, this directly caused the original unit tests to fail and then started to get httpcontext.

1. Use ASP. NET unit test provided by Visual Studio

At the beginning, I looked at the tested code. Although httpcontext is used, there are many places that I can go around. This means that httpcontext is only a parameter required for the above name, as long as it is not null, it does not affect my testing, so I use ASP. net unit test method to obtain an httpcontext. This method is the easiest to implement, but there are some problems that will be mentioned later.

Create a new web project, and then mount the tested HTTP module to the new web project. Then you can configure ASP. Net unit tests to transform the original unit tests into an ASP. NET unit test. Follow these steps to add the following attributes before the test method:

123
[HostType("ASP.NET")][UrlToTest("http://localhost:6988/Default.aspx")][AspNetDevelopmentServerHost("D:\\MS_Code\\Public\\UrlRouter.WebTest", "/")]

[Urltotest]-This attribute specifies the URL when the unit test is run.

[Hosttype]-generally, the unit test runs under the host process of vstest, so there is no httpcontext. If it is used as an ASP. net unit test, it must be in ASP.. Net host process

[Aspnetdevelopmentserverhost]-since I use ASP. NET development server as the testing host server, rather than IIS, I need to set this attribute to specify the full path of the Web application. Here, I need to point the directory to the path of the newly created web project. In this way, you can directly use httpcontext. Current in the unit test to obtain an httpcontext.

1234567891011
[[TestMethod][HostType("ASP.NET")][AspNetDevelopmentServerHost("D:\\MS_Code\\Public\\UrlRouter.WebTest", "/")][UrlToTest("http://localhost:6988/Default.aspx")]public void Fuseaction_PUT(){    handler = new UrlMapHandler(HttpContext.Current);    Assert.IsNotNull(handler);    result = handler.ExecuteUrlMap();    StringAssert.Contains(result.Url, "expected string");}

In this way, the problem of httpcontext is solved, but the following problems may occur:

  1. Uncontrollable content of httpcontext
  2. You need to run ASP. NET development server
  3. Debugging is not allowed.

2. directly create an httpcontext instance

Based on the three shortcomings mentioned above, I decided to create an httpcontext directly to solve the problem. Fortunately, httpcontext has a public constructor. This constructor must accept an httpworkerrequest as a parameter. httpworkerrequest is an abstract class and cannot be instantiated directly. However, the good news is that, microsoft has a simple class "simpleworkerrequest", which implements the httpworkerrequest class. Below is a simple code

1234
TextWriter tw = new StringWriter();HttpWorkerRequest wr = new SimpleWorkerRequest("default.aspx", "friendId=1300000000", tw);HttpContext.Current = new HttpContext(wr);

In this way, httpcontext can be used in unit testing, with the following benefits:

  1. The content of httpcontext can be controlled. For URL rewriting, The Request Path and querystring will be concerned. These two parameters can be passed as parameters when simpleworkerrequest is instantiated.
  2. ASP. NET development server is not required. This is important because it can meet the requirements of a self-contained unit test.
  3. Debuggable

3. Improved Solution

At this point, the world is wonderful and the test is going smoothly. Not long before, I encountered another problem. This URL rewriting module also applied a rule engine, which performed a lot of operations on host judgment. Unfortunately, httpcontext created in the previous method, which returns the request. in the URL, the host will always be 127.0.0.1, which is very depressing. At this time, all the people who are doing. NET will need to use the Dragon Sword !. Net reflector, use reflector to open system. web. DLL, find system. web. hosting namespace, find the simpleworkerrequest class, and find the getlocaladdress () method in it, and find that there is a hard-Code address: 127.0.0.1; well, you know where the problem is, handwritten a new class that inherits simpleworkerrequest and then overwrites its getlocaladdress () method:

123456789101112131415
public class MyWorkerRequest : SimpleWorkerRequest{     private string localAdd = string.Empty;     public MyWorkerRequest(string page, string query, TextWriter output, string address)        : base(page, query, output)    {          this.localAdd = address;    }     public override string GetLocalAddress()    {        return this.localAdd;    }}

In this way, httpcontext is instantiated like this:

1234567
Thread.GetDomain().SetData(".appPath", "c:\\inetpub\\wwwroot\\webapp\\");Thread.GetDomain().SetData(".appVPath", "/");TextWriter tw = new StringWriter();String address = "home.myspace.cn";HttpWorkerRequest wr = new MyWorkerRequest("default.aspx", "friendId=1300000000", tw, address);HttpContext.Current = new HttpContext(wr);

It should be noted that the settings for. apppath and. appvpath are required, because these two values are taken in the simpleworkerrequest constructor.
After such transformation, the test needs have been basically met.

Summary:

  1. It took more than a day to solve this problem. Later, I found that the solution was in my subscribed blog. In the future, I would like to find a Google Reader.
  2. Multiple Use of. Net reflector. Visual Studio often allows you to view meta data. Meta data is useless to us at all. It is better to use reflector.

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.