在单元测试方面,并在Web Forms和MVC方面的HttpContext和HttpContextWrapper的区别 [英] Difference between HttpContext and HttpContextWrapper in terms of Unit Testing and in terms of Web Forms and MVC

查看:163
本文介绍了在单元测试方面,并在Web Forms和MVC方面的HttpContext和HttpContextWrapper的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道的区别的HttpContext HttpContextWrapper 低于...

的HttpContext

这是老式asp.net环境。与此的问题是,它没有基类,而不是虚拟的,并且因此是不可用的用于测试(无法模拟它)。我们推荐绕不把它作为函数的参数,而不是绕过类型的变量HttpContextBase。

HttpContextBase

这是(新的C#3.5)更换为HttpContext的。因为它是抽象的,它是现在mockable。这个想法是你的职责是希望传递一个上下文应该会收到其中之一。它是由具体HttpContextWrapper

实施

HttpContextWrapper

在C#3.5还新的 - 这是具体落实HttpContextBase的。要在正常的网页上创建其中的一个,使用新HttpContextWrapper(HttpContext.Current)。

的想法是,让你的code单元测试的,您声明所有的变量和函数参数的类型为HttpContextBase的,并使用IOC框架如温莎城堡得到它注入。在正常code,城堡注入的新相当于HttpContextWrapper
(HttpContext.Current),而在测试code你给予的HttpContextBase。一个模拟

但是我不知道关于它的实际使用。我听说,这是非常有用的单元测试与Web窗体进行比较。但如何它有用吗?


我也知道,我们可以用它来执行控制器和行动这里提到


解决方案

  

我听说,这是非常有用的单元测试与Web窗体进行比较。但如何它是有用的?


让我们来这是加入一个cookie来响应一个ASP.NET MVC控制器操作的例子:

 公共类HomeController的:控制器
{
    公众的ActionResult指数()
    {
        VAR饼干=新的HttpCookie(富,酒吧);
        this.Response.Cookies.Add(饼干);
        返回查看();
    }
}

注意,响应特性那边。这是一个的Htt presponseBase 。因此,我们可以在一个单元测试嘲笑它:

 公共类的Htt presponseMock:Htt的presponseBase
{
    私人HttpCookieCollection饼干;
    公众覆盖HttpCookieCollection饼干
    {
        得到
        {
            如果(this.cookies == NULL)
            {
                this.cookies =新HttpCookieCollection();
            }            返回this.cookies;
        }
    }
}公共类HttpContextMock:HttpContextBase
{
    私人的Htt presponseBase响应;    公共覆盖的Htt presponseBase响应
    {
        得到
        {
            如果(this.response == NULL)
            {
                this.response =新的Htt presponseMock();
            }
            返回this.response;
        }
    }
}

现在我们可以写一个单元测试:

  //安排
VAR SUT =新的HomeController();
VAR的HttpContext =新HttpContextMock();
sut.ControllerContext =新的ControllerContext(HttpContext的,新的RouteData(),SUT);//行为
VAR实际= sut.Index();//断言
Assert.AreEqual(酒吧,sut.Response.Cookies [富]值。);

由于所有成员都是虚拟的,我们可以用嘲弄的框架,以避免我们需要写这些mock类的单元测试。例如与 NSubstitute 的,这里的测试会是什么样子:

  //安排
VAR SUT =新的HomeController();
VAR背景= Substitute.For< HttpContextBase>();
VAR响应= Substitute.For< Htt的presponseBase>();
VAR饼干=新HttpCookieCollection();
context.Response.Returns(响应);
context.Response.Cookies.Returns(饼干);
sut.ControllerContext =新的ControllerContext(背景下,新的RouteData(),SUT);//行为
VAR实际= sut.Index();//断言
Assert.AreEqual(酒吧,sut.Response.Cookies [富]值。);

现在让我们来一个WebForm:

 保护无效的Page_Load(对象发件人,EventArgs)
{
    VAR饼干=新的HttpCookie(富,酒吧);
    this.Response.Cookies.Add(饼干);
}

在这种情况下,响应特性是具体的的Htt presponse 。所以,你打掉。不可能孤立的单元测试。

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

HttpContext

This is the vintage asp.net context. The problem with this is that it has no base class and isn't virtual, and hence is unusable for testing (cannot mock it). It's recommended to not pass it around as function arguments, instead pass around variables of type HttpContextBase.

HttpContextBase

This is the (new to c# 3.5) replacement to HttpContext. Since it is abstract, it is now mockable. The idea is that your functions that expect to be passed a context should expect to receive one of these. It is concretely implemented by HttpContextWrapper

HttpContextWrapper

Also new in C# 3.5 - this is the concrete implementation of HttpContextBase. To create one of these in a normal webpage, use new HttpContextWrapper(HttpContext.Current).

The idea is that to make your code unit-testable, you declare all your variables and function parameters to be of type HttpContextBase, and use an IOC framework eg Castle Windsor to get it injected. In normal code, castle is to inject the equivalent of 'new HttpContextWrapper (HttpContext.Current)', whereas in test code you're to be given a mock of HttpContextBase.

But I am not aware about its real use. I heard that it's useful in Unit Testing in comparing with Web Forms. but how it's useful ?


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

解决方案

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

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.

这篇关于在单元测试方面,并在Web Forms和MVC方面的HttpContext和HttpContextWrapper的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆