首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >HttpContext和HttpContextWrapper在单元测试、Web Forms和MVC方面的差异

HttpContext和HttpContextWrapper在单元测试、Web Forms和MVC方面的差异
EN

Stack Overflow用户
提问于 2013-05-27 13:59:28
回答 1查看 10.3K关注 0票数 18

我知道HttpContextHttpContextWrapper之间的区别如下...

HttpContext

这是老式的asp.net上下文。这样做的问题是它没有基类,也不是虚拟的,因此不能用于测试(不能模拟它)。建议不要将其作为函数参数传递,而应传递HttpContextBase类型的变量。

HttpContextBase

这是HttpContext的( c# 3.5的新版本)替代品。因为它是抽象的,所以现在它是可模拟的。这个想法是希望传递给上下文的函数应该能够接收到其中的一个。具体由HttpContextWrapper实现

HttpContextWrapper

这也是C# 3.5中的新特性--这是HttpContextBase的具体实现。要在普通网页中创建其中一个,请使用新的HttpContextWrapper(HttpContext.Current)。

这个想法是,为了使你的代码可单元测试,你声明你的所有变量和函数参数都是HttpContextBase类型的,并使用IOC框架,例如Castle Windsor来注入它。在正常代码中,castle将注入等同于“new HttpContextWrapper (HttpContext.Current)”的内容,而在测试代码中,您将获得HttpContextBase的模拟。

,但我不知道它的真正用途。我听说与Web表单相比,它在单元测试中很有用。但是它有什么用呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-27 14:09:59

我听说它在单元测试中与Web Forms相比很有用。但是它有什么用呢?

让我们以一个向响应添加cookie的ASP.NET MVC控制器操作为例:

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

请注意那里的Response属性。这是个HttpResponseBase。所以我们可以在单元测试中模拟它:

代码语言:javascript
复制
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;
        }
    }
}

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

代码语言:javascript
复制
// 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);

由于所有成员都是虚拟的,我们可以使用模拟框架,这样就不需要为单元测试编写那些模拟类了。例如,对于NSubstitute,测试可能是这样的:

代码语言:javascript
复制
// 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);

现在让我们来看一个WebForm:

代码语言:javascript
复制
protected void Page_Load(object sender, EventArgs)
{
    var cookie = new HttpCookie("foo", "bar");
    this.Response.Cookies.Add(cookie);
}

在本例中,Response属性是具体的HttpResponse。所以你被抓了。不可能在隔离中进行单元测试。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16767131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档