我正在尝试为我的控制器创建一个单元测试,但我正在测试的操作使用了一个部分视图到字符串函数,它不想在我的测试中工作。
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);
行上给出了“对象引用未设置为对象实例”的错误
我在控制器的单元测试中的设置是(删除了几个位以简化它):
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;
我没有运气试图寻找解决方案或解决问题。任何帮助赞赏。感谢。
正如我所建议的那样,我尝试设置路由数据但仍然收到错误。这是我添加的内容:
var routeData = new RouteData();
routeData.Values.Add("controller", "BlogController");
mock.SetupGet(m => m.RouteData).Returns(routeData);
答案 0 :(得分:21)
最后的解决方案感谢评论中的帮助。
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;
答案 1 :(得分:1)
这是一个使用AutoMoq的版本,可以呈现您选择的字符串。
Subject.ControllerContext = new ControllerContext(
Mocked<HttpContextBase>().Object,
new RouteData(),
Subject);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(Mocked<IViewEngine>().Object);
Mocked<IViewEngine>()
.Setup(x => x.FindPartialView(Subject.ControllerContext,
It.IsAny<string>(), It.IsAny<bool>()))
.Returns(new ViewEngineResult(Mocked<IView>().Object,
Mocked<IViewEngine>().Object));
Mocked<IView>()
.Setup(x => x.Render(It.IsAny<ViewContext>(), It.IsAny<TextWriter>()))
.Callback((ViewContext c, TextWriter w) => w.WriteLine("RENDERED"));