views:

1670

answers:

1

I've been using the MvcMockHelpers class found at Hanselman's blog for passing in a mocked HttpContext. We extended it somewhat to add some authentication data we needed and for the most part this has been great.

The issue we are having is that the context we are giving to the controller has a null value in the HttpContext.Response.Output, which is causing some exceptions to be thrown. I'm not sure what to add to get this working.

Here is the existing FakeHttpConext() method:

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

        // Our identity additions ...
        var user = new Mock<IPrincipal>();
        OurIdentity identity = (OurIdentity)Thread.CurrentPrincipal.Identity;

        context.Expect(ctx => ctx.Request).Returns(request.Object);
        context.Expect(ctx => ctx.Response).Returns(response.Object);
        context.Expect(ctx => ctx.Session).Returns(session.Object);
        context.Expect(ctx => ctx.Server).Returns(server.Object);
        context.Expect(ctx => ctx.User).Returns(user.Object);
        context.Expect(ctx => ctx.User.Identity).Returns(identity);
        return context.Object;
    }

Here is the exploding method (which is part of the MVC Contrib project's XmlResult):

    public override void ExecuteResult(ControllerContext context)
    {
        if (_objectToSerialize != null)
        {
           var xs = new XmlSerializer(_objectToSerialize.GetType());
           context.HttpContext.Response.ContentType = "text/xml";
           xs.Serialize(context.HttpContext.Response.Output, _objectToSerialize);
        }
    }

What do I need to add in the FakeHttpContext method to prevent the null exception when the context.HttpContext.Response.Output is referenced?

Clarification: The solution I'm looking for needs to be done in Moq, not Rhino. I mentioned Moq in the question title but neglected that in question body. Sorry for any confusion.

Resolution I added the following two lines of code to the FakeHttpContext() method:

var writer = new StringWriter();
context.Expect(ctx => ctx.Response.Output).Returns(writer);

This prevents the null exception. Not sure if its a good answer long term, but it works for now.

+2  A: 

In the Tests for MvcContrib (http://www.codeplex.com/mvcContrib) the file MvcMockHelps shows how it is done.

Matthew
The MVC Contrib project uses RhinoMocks, not Moq. I can get the unit test to work using Rhino, but Rhino is not what our office has standardized on.
Sailing Judo
What you need to do is make a call to the mockedRequest.Output return a TextWriter and mockedRequest.OutputStream return a stream such as a MemoryStream.
Matthew
Yes... this is the part I dont know how to do. Still trying different things.
Sailing Judo
I just figured it out finally... thanks for the input.
Sailing Judo
Glad it worked for you.
Matthew