简体   繁体   English

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

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

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); 这给了我一个错误:“对象引用没有设置为对象的实例”在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);

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;

Here's a version using AutoMoq that renders a string of your choice. 这是使用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"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何模拟Request.Url.GetLeftPart()以便我的单元测试通过 - How can I mock Request.Url.GetLeftPart() so my unit test passes 如何从控制器返回局部视图以显示在主视图中? - How do I return a partial view from my controller to display on my main view? 如何在单元测试中模拟字符串响应? - How do I mock a string response in a Unit Test? 如何使用Mock测试我的控制器? - How can I use Mock to test my controller? 如何对实体上下文进行单元测试 - How I can unit-test my entity context 单元测试模拟控制器,C#我需要模拟HTTPContext吗? 我要嘲笑什么方法? - Unit Test Mock Controller, C# Do I need to Mock HTTPContext? What methods do I mock? 如何使用或模拟 IWebJobsBuilder 对 Azure Function v2 进行集成测试? - How can I use or mock IWebJobsBuilder to do an integration test of my Azure Function v2? 如何在没有SecurityException的Silverlight视图模型中为此方法编写单元测试? - How do I write a unit test for this method in my view model in Silverlight without SecurityException? 如何正确模拟HttpContextBase,以便我的单元测试正常工作 - How to Mock HttpContextBase correctly so my unit tests are working 我应该模拟ControllerContext来对我的JsonNetResult数据进行单元测试 - Should I mock the ControllerContext to unit test my JsonNetResult data
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM