如何使用Rhino Mocks来模拟HttpContext.Application

时间:2009-04-01 14:41:11

标签: asp.net-mvc rhino-mocks httpcontext

我是Mocking框架的新手,并已开始使用RhinoMocks来协助我的MVC应用单元测试。

我正在使用Scott Hanselmanns MVC Mock Helper来帮助模拟HttpContext。 我已经成功地(经过一段时间)嘲笑了我需要的一些东西,但是当涉及到HttpContext的Application属性时,它已经失败了。

在我的应用程序中,我将一个对象存储在Application中,并在Controller中检索它,如:

SomeObj foo = (SomeObj)Application["fooKey"];

这是在我的MVC App中的Application_Start上创建的。

更新后的第一个答案(为了清晰起见,附加代码) 目前在测试设置中我做了:

HttpContextBase mockHttpBase = mocks.FakeHttpContext();
controllerToTest = new SomeController();
mocks.SetFakeControllerContext(controllerToTest);


HttpApplicationStateBase appState = 
    MockRepository.GenerateStub<HttpApplicationStateBase>();

Globals tmpAppGlobals = 
    new Globals();

mockHttpBase.Expect(ctx => ctx.Application).Return(appState);
mockHttpBase.Expect(ctx => ctx.Application[Globals.GlobalsKey]).
    Return(tmpAppGlobals);

在我的单元测试设置中,我做了:

Globals tmpAppGlobals = new Globals();
controllerToTest.ControllerContext.HttpContext.
            Expect(ctx => ctx.Application[Globals.GlobalsKey]).
Return(tmpAppGlobals);

此调用将为Application对象抛出NullReference异常。

我的问题有两个:

1)这是正确的方法还是我从设计/架构的角度做错了什么?

2)为什么这不起作用?!

提前谢谢。

2 个答案:

答案 0 :(得分:1)

如果不深入研究,这看起来大多是正确的。

Application属性在HttpContextBase上是虚拟的,所以你应该可以从Rhino设置它的返回值 - 假设你正在像Scott Hanselmanns的帖子那样嘲笑HttpContextBase。

一些可能的原因,实际上只是缺乏信息的猜测:

  • 您是否设置了退货 controllerToTest.ControllerContext?
  • 您是否为 设置了回报 对象HttpContext属性?
  • 您是否为 设置了回报 对象应用程序属性?

我问的原因是,通常在进行期望设置时,您已经引用了将作为测试的一部分调用的对象,因此您不会像使用{{1调用。

修改:

我想我看到了问题,我认为这是与这一部分有关的:

controllerToTest.ControllerContext.HttpContext. Expect()

我认为你假设索引器与属性的工作方式相同,而不是。您真正需要做的是在Expect(ctx => ctx.Application[Globals.GlobalsKey])对象上设置一个期望来接收对Item属性的调用,如下所示:

appState

答案 1 :(得分:1)

你可以使用下面的Moq。我花了一段时间来模拟HttpApplication,appState.Object是返回方法duh!

public static HttpContextBase FakeHttpContext()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new FakeHttpSessionState();
        var server = new Mock<HttpServerUtilityBase>();
        var appState = new Mock<HttpApplicationStateBase>();

        context.Setup(ctx => ctx.Request).Returns(request.Object);
        context.Setup(ctx => ctx.Response).Returns(response.Object);
        context.Setup(ctx => ctx.Session).Returns(session);
        context.Setup(ctx => ctx.Server).Returns(server.Object);
        context.Setup(ctx => ctx.Application).Returns(appState.Object);

        //emulate session (HttpContext.Current.Session) 
        var contx = new HttpContext(new MyApp.NUnit.Tests.Fakes.FakeHttpWorkerRequest());
        contx.Items["AspSession"] = CreateSession();

        HttpContext.Current = contx;

        return context.Object;
    }