2013-05-27 25 views
17

Tôi biết sự khác biệt giữa HttpContextHttpContextWrapper được dưới ...Sự khác nhau giữa HttpContext và HttpContextWrapper về đơn vị kiểm tra và về Web Forms và MVC

HttpContext

Đây là asp cổ điển .net context. Vấn đề với điều này là nó không có lớp cơ sở và không phải là ảo, và do đó không thể sử dụng được để thử nghiệm (không thể giả lập nó). Chúng tôi khuyên bạn không nên chuyển nó xung quanh làm đối số hàm, thay vì chuyển qua các biến kiểu HttpContextBase.

HttpContextBase

Đây là (mới để C# 3.5) thay thế để HttpContext. Vì nó là trừu tượng, nó bây giờ là mockable. Ý tưởng là các chức năng của bạn được mong đợi để được thông qua một bối cảnh nên mong đợi để nhận được một trong những điều này. Nó được cụ thể thực hiện bởi HttpContextWrapper

HttpContextWrapper

Cũng mới trong C# 3.5 - đây là việc thực hiện cụ thể của HttpContextBase. Để tạo một trong số này trong một trang web bình thường, hãy sử dụng HttpContextWrapper (HttpContext.Current) mới.

Ý tưởng là để làm cho mã của bạn có thể kiểm thử được, bạn khai báo tất cả các biến và tham số chức năng của bạn là loại HttpContextBase và sử dụng khung IOC ví dụ Castle Windsor để tiêm nó. Trong mã bình thường, lâu đài là để tiêm tương đương với 'mới HttpContextWrapper (HttpContext.Current)', trong khi trong mã thử nghiệm bạn sẽ được đưa ra một giả HttpContextBase.

Nhưng tôi không biết về việc sử dụng thực sự của nó. Tôi nghe nói rằng nó hữu ích trong bài kiểm tra đơn vị so với các biểu mẫu Web. nhưng nó hữu ích như thế nào?


I also know that we can use it to execute the controller and Action as mentioned here

Trả lời

18

Tôi nghe nói rằng đó là hữu ích trong việc kiểm tra Đơn vị khi so sánh với Web Forms. nhưng nó hữu ích như thế nào?

Hãy lấy một ví dụ về một hành động điều khiển ASP.NET MVC được thêm một cookie để phản ứng:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var cookie = new HttpCookie("foo", "bar"); 
     this.Response.Cookies.Add(cookie); 
     return View(); 
    } 
} 

Thông báo tài sản đáp ứng đằng kia. Đó là một số HttpResponseBase. Vì vậy, chúng ta có thể thử nó trong một thử nghiệm đơn vị:

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; 
     } 
    } 
} 

và bây giờ chúng tôi có thể viết một bài kiểm tra đơn vị:

// 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); 

Và vì tất cả các thành viên là ảo chúng ta có thể sử dụng một khuôn khổ mocking đó sẽ tránh cho chúng ta cần phải viết các lớp mô phỏng đó cho bài kiểm tra đơn vị.Ví dụ với NSubstitute dưới đây là cách kiểm tra có thể xem xét:

// arrange 
var sut = new HomeController(); 
var context = Substitute.For<HttpContextBase>(); 
var response = Substitute.For<HttpResponseBase>(); 
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); 

Bây giờ chúng ta hãy WebForm:

protected void Page_Load(object sender, EventArgs) 
{ 
    var cookie = new HttpCookie("foo", "bar"); 
    this.Response.Cookies.Add(cookie); 
} 

Trong trường hợp này tài sản đáp ứng là bê tông HttpResponse. Vì vậy, bạn đang bị vỡ. Không thể kiểm tra đơn vị trong sự cô lập.

+0

Điều đó có nghĩa là NVC có các phương thức Hành động có thể được gọi trong Dự án thử nghiệm đơn vị và mặt khác biểu mẫu web không có phương thức thay vì nó có sự kiện tải trang. Vì vậy, không thể được gọi trực tiếp? –

+1

Không, có nghĩa là Bộ điều khiển MVC đã làm việc với các lớp trừu tượng (HttpContextBase, HttpResponseBase, HttpRequestBase, ...) trong khi một WebForm làm việc với các lớp cụ thể (HttpContext, HttpResponse, HttpRequest, ...). ASP.NET MVC được thiết kế với điều này trong tâm trí để tất cả các tài sản và các thành viên tiếp xúc với khung là trừu tượng và không phải là các lớp cụ thể. –

+0

Tôi đã kiểm tra siêu dữ liệu của 'httpresponse' và' httpresponsebase'. Cả hai đều có cùng số thuộc tính và phương thức. Vì vậy, không có sự khác biệt giữa chúng. đúng ? –

Các vấn đề liên quan