如何在unit testing中模拟控制器上下文,以便我对字符串函数的部分视图有效?

我正在尝试为我的控制器创建一个unit testing,但我正在测试的操作使用部分视图来查看不希望在我的测试中工作的字符串函数。

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(); } } 

这给了我一个错误“对象引用未设置为对象的实例”在ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);

我在控制器的unit testing中的设置是(删除了几个位以简化它):

 var mock = new Mock(); 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; 

我没有运气试图寻找解决方案或解决问题。 任何帮助赞赏。 谢谢。


正如所建议的那样,我尝试设置路由数据,但仍然收到错误。 这就是我添加的内容:

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

最后的解决方案感谢评论中的帮助。

 var mock = new Mock(); 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(); var engine = new Mock(); var viewEngineResult = new ViewEngineResult(view.Object, engine.Object); engine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny(), It.IsAny())).Returns(viewEngineResult); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(engine.Object); var controller = new BlogController(); controller.ControllerContext = mock.Object; 

这是一个使用AutoMoq的版本,可以呈现您选择的字符串。

 Subject.ControllerContext = new ControllerContext( Mocked().Object, new RouteData(), Subject); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(Mocked().Object); Mocked() .Setup(x => x.FindPartialView(Subject.ControllerContext, It.IsAny(), It.IsAny())) .Returns(new ViewEngineResult(Mocked().Object, Mocked().Object)); Mocked() .Setup(x => x.Render(It.IsAny(), It.IsAny())) .Callback((ViewContext c, TextWriter w) => w.WriteLine("RENDERED"));