ASP.NET MVC - Unit testing RenderPartialViewToString() with Moq framework?
Asked Answered
J

1

6

I'm using this helper method to turn my PartialViewResult into string and returning it as Json - http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/

My problem is that I'm using Moq to mock the controller, and whenever I run unit test that uses this RenderPartialViewToString() method, I got the "Object reference not set to an instance of an object." error on ControllerContext.

private ProgramsController GetController()
{
var mockHttpContext = new Mock<ControllerContext>();
mockHttpContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("test");
mockHttpContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
// Mock Repositories
var mockOrganizationRepository = new MockOrganizationRepository(MockData.MockOrganizationsData());
var mockIRenderPartial = new BaseController();
var controller = new ProgramsController(mockOrganizationRepository, mockIRenderPartial);
controller.ControllerContext = mockHttpContext.Object;
return controller;
}

This returns a proxy controller, and maybe it's the reason why I got that error. Any idea how to unit testing this?

Thank you very much.

Johnsson answered 1/9, 2010 at 20:35 Comment(3)
Where exactly does the NullReferenceException occur?Book
It occurs on ControllerContext, I think because of Moq is mocking the controller and only returning the proxy... This is the line: ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ControllerContext.Controller is null when I hover over it. Thanks,Johnsson
I'm getting this exception as well, after setting the "controller" and "action" parameters in the RouteData. Full stack trace: pastebin.com/S8c26JLDWholewheat
B
4

try this:

public static void SetContext(this Controller controller)
        {
            var httpContextBase = new Mock<HttpContextBase>();
            var httpRequestBase = new Mock<HttpRequestBase>();
            var respone = new Mock<HttpResponseBase>();
            var session = new Mock<HttpSessionStateBase>();
            var routes = new RouteCollection();
            RouteConfigurator.RegisterRoutesTo(routes);

            httpContextBase.Setup(x => x.Response).Returns(respone.Object);
            httpContextBase.Setup(x => x.Request).Returns(httpRequestBase.Object);
            httpContextBase.Setup(x => x.Session).Returns(session.Object);
            session.Setup(x => x["somesessionkey"]).Returns("value");
            httpRequestBase.Setup(x => x.Form).Returns(new NameValueCollection());
            controller.ControllerContext = new ControllerContext(httpContextBase.Object, new RouteData(), controller);
            controller.Url = new UrlHelper(new RequestContext(controller.HttpContext, new RouteData()), routes);
        }
Becky answered 8/9, 2010 at 7:40 Comment(6)
Hi Omu, I'm having this error on this line: ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); The error is "The RouteData must contain an item named 'controller' with a non-empty string value." Thanks.Johnsson
I tried but no luck, same error :( *** Edited *** How do you manually add a controller variable to the RouteData?Johnsson
add your stuff between these 2 lines: var routes = new RouteCollection(); RouteConfigurator.RegisterRoutesTo(routes);Becky
are you using some custom ViewEngine ?Becky
No, I'm using the MVC ViewEngine, together with the method to renders the view as string. I'm not sure where the problem lies.Johnsson
You need to mock view engine too. Check this out: #3462506Laughingstock

© 2022 - 2024 — McMap. All rights reserved.