惩戒HttpContextBase与起订量 [英] Mocking HttpContextBase with Moq

查看:138
本文介绍了惩戒HttpContextBase与起订量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这我想这是用于隶属函数在一个Web应用程序的ASP.NET MVC控制器上测试ControllerAction单元测试夹具。我想嘲笑为测试HttpContext的。被测ControllerAction实际上是设置在HttpContext的属性,如会话值,Response.Cookies值等,这是不是所有的code,但这里是我想测试一个粗略的样本获得运行:

I have a unit test fixture in which I'm trying to test a ControllerAction on an ASP.NET MVC controller that's used for membership functions on a web app. I'm trying to mock the HttpContext for the tests. The ControllerAction under test actually sets properties on the HttpContext, such as Session values, Response.Cookies values, etc. This isn't all of the code, but here is a rough sample of the test that I'm trying to get to run:

[Test]
public void ValidRegistrationDataSuccessfullyCreatesAndRegistersUser()
{
    var context = new Mock<HttpContextBase>() {DefaultValue = DefaultValue.Mock};
    context.SetupAllProperties();
    var provider = new Mock<MembershipProvider>(new object[] {context.Object});
    var controller = new AccountController(context.Object, provider.Object);
    // This just sets up a local FormCollection object with valid user data 
    // in it to use to attempt the registration
    InitializeValidFormData();
    ActionResult result = controller.Register(_registrationData);
    Assert.IsInstanceOfType(typeof(ViewResult), result);
    // Here is where I'd like to attempt to do Assertions against properties 
    // of the HttpContext, like ensuring that a Session object called "User" 
    // exists, and new auth cookie exists on the Response.Cookies collection. 
    // So far I've been unable to successfully check the values of those properties.
    // I've been unsuccessful in getting those properties setup correctly on my 
    // mock object so that my ControllerAction can actually *set* their values, 
    // and that I can make assertions on them afterwards. The above code actually
    // generates a StackOverflowException (which I've reported) on the
    // context.SetupAllProperties() call. What am I doing wrong, or what do I need 
    // to do to be able to set and assert on those context properties?
}

不知道我做错了,但我喜欢它,如果有人可以点我在正确的方向,告诉我如何设置,这样我的控制器实际上可以在其属性值设置模拟这个对象HttpContextBase和我可以对这些属性断言,以确保我的ControllerAction是做什么我需要它。

Not sure what I'm doing wrong, but I'd love it if someone could point me in the right direction and show me how to setup this mock HttpContextBase object such that my controller can actually set values on its properties, and I can make assertions on those properties to ensure that my ControllerAction is doing what I need it to.

我是不是接近这个错误的方式?我知道MVC控制器有一个ControllerContext,我可以用它来进行会​​话等设置的值,但我无法弄清楚如何这样的事情可以不注射就被嘲笑。有没有这样做,而不是某种方式? (我还需要能够通过上下文到我的MembershipProvider太)那会是一个更好的方法吗?

Am I approaching this the wrong way? I know that MVC Controllers have a ControllerContext that I can use to set values for Session, etc, but I can't figure out how something like that could be mocked without injecting it. Is there some way of doing that instead? (I also need to be able to pass the context in to my MembershipProvider too) Would that be a better approach?

感谢。

推荐答案

我使用一个版本的一些code史蒂夫·桑德森收录在他的临Asp.NET MVC本书 ......,我现在有一个道德困境是否也没关系张贴在这里的code。怎么样我一个高度精简版妥协? ;)

I'm using a version of some code Steve Sanderson included in his Pro Asp.NET MVC book... and I'm currently having a moral dilemma whether it's okay to post the code here. How about I compromise with a highly stripped down version? ;)

因此​​,这可以很容易地被重用,创建与下图类似一个你会把你的控制器类。这将设置你的嘲弄,并将其设置为您控制器的ControllerContext

So this can easily be reused, create a class similar to the one below that you will pass your controller. This will set up your mocks and set them to your controller's ControllerContext

public class ContextMocks
{
    public Moq.Mock<HttpContextBase> HttpContext { get; set; }
    public Moq.Mock<HttpRequestBase> Request { get; set; }
    public RouteData RouteData { get; set; }

    public ContextMocks(Controller controller)
    {
        //define context objects
        HttpContext = new Moq.Mock<HttpContextBase>();
        HttpContext.Setup(x => x.Request).Returns(Request.Object);
        //you would setup Response, Session, etc similarly with either mocks or fakes

        //apply context to controller
        RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
        controller.ControllerContext = new ControllerContext(rc, controller);
    }
}

然后在您的测试方法,你只是创建ContextMocks的实例,并在传递正在测试的控制器对象:

And then in your test method you'd just create an instance of ContextMocks and pass in the controller object you're testing:

[Test]
Public void test()
{
     var mocks = new ContextMocks(controller);
     var req = controller.Request; 
     //do some asserts on Request object
}

似乎非常类似于克雷格的实施例,但是这是与起订量v3的。我必须给道具史蒂夫·桑德森这个 - 我使用这个作为基础测试各种否则传统难以测试的东西:Cookie,会话,请求方法,查询字符串和多个

Seems very similar to Craig's examples, but this is with Moq v3. I have to give props to Steve Sanderson for this - I'm using this as a basis for testing all kinds of otherwise traditionally hard-to-test stuff: cookies, session, request method, querystring and more!

这篇关于惩戒HttpContextBase与起订量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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