How do I mock controller context in my unit test so that my partial view to string function works?

asp.net-mvc-5, c#, moq, unit-testing

Solution

Final solution thanks to help in the comments.

var mock = new Mock<ControllerContext>();
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
if (userName != null)
{
   mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
   mock.SetupGet(p => p.HttpContext.User.Identity.IsAuthenticated).Returns(true);
}
else
{
   mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(false);
}

var routeData = new RouteData();
routeData.Values.Add("controller", "BlogController");
mock.SetupGet(m => m.RouteData).Returns(routeData);

var view = new Mock<IView>();
var engine = new Mock<IViewEngine>();
var viewEngineResult = new ViewEngineResult(view.Object, engine.Object);
engine.Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), It.IsAny<string>(), It.IsAny<bool>())).Returns(viewEngineResult);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(engine.Object);

var controller = new BlogController();
controller.ControllerContext = mock.Object;

Problem

I am attempting to create a unit test for my controller, but the action I am testing uses a partial view to string function which doesn't want to work in my tests. ``` private string RenderPartialViewToString(string viewName, object model = null) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.RouteData.GetRequiredString("action"); ViewData.Model = model; using (System.IO.StringWriter sw = new System.IO.StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } ``` This gives me an error of "Object reference not set to an instance of an object" on the line `ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);` My setup in the unit test for the controller is (with a few bits removed to simplify it): ``` var mock = new Mock<ControllerContext>(); mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName); if (userName != null) { mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true); mock.SetupGet(p => p.HttpContext.User.Identity.IsAuthenticated).Returns(true); } else { mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(false); } var controller = new BlogController(); controller.ControllerContext = mock.Object; ``` I've not had any luck trying to find a solution or work around. Any help appreciated. Thanks. As suggested I have tried setting up route data but still getting the error. This is what I have added: ``` var routeData = new RouteData(); routeData.Values.Add("controller", "BlogController"); mock.SetupGet(m => m.RouteData).Returns(routeData); ```

Original source

Related problems