I know the difference between HttpContext
and HttpContextWrapper
is below...
HttpContext
This is the vintage asp.net c
I heard that it's useful in Unit Testing in comparing with Web Forms. but how it's useful ?
Let's take an example of an ASP.NET MVC controller action which is adding a cookie to the response:
public class HomeController : Controller
{
public ActionResult Index()
{
var cookie = new HttpCookie("foo", "bar");
this.Response.Cookies.Add(cookie);
return View();
}
}
Notice the Response property over there. It's an HttpResponseBase
. So we can mock it in a unit test:
public class HttpResponseMock: HttpResponseBase
{
private HttpCookieCollection cookies;
public override HttpCookieCollection Cookies
{
get
{
if (this.cookies == null)
{
this.cookies = new HttpCookieCollection();
}
return this.cookies;
}
}
}
public class HttpContextMock: HttpContextBase
{
private HttpResponseBase response;
public override HttpResponseBase Response
{
get
{
if (this.response == null)
{
this.response = new HttpResponseMock();
}
return this.response;
}
}
}
and now we could write a unit test:
// arrange
var sut = new HomeController();
var httpContext = new HttpContextMock();
sut.ControllerContext = new ControllerContext(httpContext, new RouteData(), sut);
// act
var actual = sut.Index();
// assert
Assert.AreEqual("bar", sut.Response.Cookies["foo"].Value);
And since all members are virtual we could use a mocking framework which would avoid us the need to write those mock classes for the unit test. For example with NSubstitute here's how the test might look:
// arrange
var sut = new HomeController();
var context = Substitute.For();
var response = Substitute.For();
var cookies = new HttpCookieCollection();
context.Response.Returns(response);
context.Response.Cookies.Returns(cookies);
sut.ControllerContext = new ControllerContext(context, new RouteData(), sut);
// act
var actual = sut.Index();
// assert
Assert.AreEqual("bar", sut.Response.Cookies["foo"].Value);
Now let's take a WebForm:
protected void Page_Load(object sender, EventArgs)
{
var cookie = new HttpCookie("foo", "bar");
this.Response.Cookies.Add(cookie);
}
In this case the Response property is the concrete HttpResponse
. So you are busted. Impossible to unit test in isolation.