Difference between HttpContext and HttpContextWrapper in terms of Unit Testing and in terms of Web Forms and MVC

前端 未结 1 1810
甜味超标
甜味超标 2021-01-30 18:42

I know the difference between HttpContext and HttpContextWrapper is below...

HttpContext

This is the vintage asp.net c

1条回答
  •  迷失自我
    2021-01-30 18:50

    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.

    0 讨论(0)
提交回复
热议问题