views:

156

answers:

2

Since I'm having problem with unit testing RenderPartialViewToString() with Moq framework (http://stackoverflow.com/questions/3621961/asp-net-mvc-unit-testing-renderpartialviewtostring-with-moq-framework), I'm thinking about getting my controller directly, without using Moq for these particular test, however, how do I mocks (or set) the HttpContext for my test without using any Moq framework?

I need to able to do something similar to this, without Moq of course:

    var mockHttpContext = new Mock<ControllerContext>();

    mockHttpContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("n1\\test");
    mockHttpContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

Thank you very much.

A: 

I think you are looking for this: http://www.castleproject.org/dynamicproxy/index.html

Omu
+1  A: 

If your controller need authentication info from HttpContext, I would:

  1. Create a new class that wraps the calls you care about. Looks like you want Name and IsAuthenticated. The new class can be AuthenticationService or something.
  2. In the methods/properties in AuthenticationService, call into the real HttpContext, like HttpContext.Current.user.Identity.Name.
  3. Create an interface over the new AuthenticationService with the public methods/properties you care about.
  4. Inject the IAuthenticationService into your controller under test in the constructor. Looks like you may already be doing that with other dependencies in the controller.
  5. Now you can mock IAuthenticationService and it's return values without needing to call into the real HttpContext.

Here are more details from a blog post I did http://www.volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext.aspx. I'm using RhinoMocks instead of Moq, but the concept is the same for staying away from HttpContext.

Joe Wilson
Thanks Joe, I got the first part working ("mocking" HttpContext), but still run into the issue of unable to test that RenderPartialViewToString() method :)
Saxman
I now see the original blog post code you're trying to test. It was a couple clicks away. That BaseController needs the same concept - a constructor with an IControllerContext (and anything else the class depends on) passed in by the calling test. Then use a private field for _controllerContext that is set in the constructor from that argument. Call this private field in the RenderPartialViewToString(string viewName, object model) method and the test should use your mocked values instead of the live ControllerContext values.
Joe Wilson