C# HttpContext Unit-Test - Write Testable ASP.NET MVC Web Application

4/1/2014·3 min read

ASP.NET MVC appliation is not only provided you more easy for building Web Application, it also build for runing your Unit-Test easily. So, there're two ways you could get value like, Session, Request, Response information.

  1. System.Web.HttpContext
  2. System.Web.HttpContextBase

So the differece of these two are, first HttpContext is sealed class, which means unable to override it and can't mock by using mock framework. On the other hand, HttpContextBase, is abstract class, which is able to override, so you could mock it by using mock framework too. In addition, ASP.NET MVC's controller was builded in for runing your unit test, so you don't need to do something like Dependencty Injection, to hack your HttpContextBase in to your unit test, you could just mock your HttpContextBase passing to your controller class. Following is example how to passing your mock data to your

How to mock and passing mock HttpContextBase to your Controller
 	private  static  AccountController  GetAccountController()
 		{
 			RequestContext  requestContext = new  RequestContext (new  MockHttpContext (), new  RouteData ());
 			AccountController  controller = new  AccountController ()
 			{
 				FormsService = new  MockFormsAuthenticationService (),
 				MembershipService = new  MockMembershipService (),
 				Url = new  UrlHelper (requestContext),
 			};
 			controller.ControllerContext = new  ControllerContext ()
 			{
 				Controller = controller,
 				RequestContext = requestContext
 			};
 			return  controller;
 		}
 
How to call httpContextBase mocked method
 	// Arrange 
 			AccountController  controller = GetAccountController();
 
 			// Act 
 			ActionResult  result = controller.ChangePassword();
 

So, once you run your unit test, it will using your mocked HttpContextBase data to runing your actual logic.

Sample code : how to mock HttpContext
 public  static  HttpContextBase  MockData()
 		{
 			Mock <HttpContextBase > httpContext = new  Mock <HttpContextBase >();
 			Mock <HttpSessionStateBase > session = new  Mock <HttpSessionStateBase >();
 			// set value => you could access on your controller 
 			httpContext.SetupGet(x => x.Session["test" ]).Returns("N" );
 
 			// set/get value => you could set and get on your controller 
 			int  id = 1;
 			session.SetupSet(x => x["test2" ] = It .IsAny<int >())
 			.Callback((string  name, object  val) =>
 			{
 				id = (int )val;
 				session.SetupGet(x => x["test2" ]).Returns(id);
 			});
 			return  httpContext.Object;
 		}
 

You would notice there're following you could access your HttpContext object, following is example for Session. So only the first one is old ASP.NET way of get / set session. The rest of them are able to access at Your Controller class. It's better not using the first one,

 System.Web.HttpContext
 

Because you can't mock the data, if you want to test it, anyway, it's better to find other way to get your data, but not using the old HttpContext on your MVC.

 

Ways of access your HttpContext(Session) object
var  session1 = System.Web.HttpContext .Current.Session;
var  session2 = this .Session;
var  session3 = this .HttpContext.Session;
var  session4 = this .ControllerContext.HttpContext.Session;
 

Inconclusion, in ASP.NET MVC, you shouldn't use System.Web.HttpContext, which'll make your life hard during unit test.