displaymode is null when mocking ControllerContext

7 posts, 0 answers
  1. Lee Saunders
    Lee Saunders avatar
    20 posts
    Member since:
    Jul 2009

    Posted 22 Apr 2013 Link to this post

    Hello,

    I'm trying to mock a controller.ControllerContext and everything is working until the system tries to GetDisplayMode on the context.  Since it is null, it blows up.

    Here are two functions, the first creates the controller and the second uses the controller and blows up.

    Any help would be appreciated!

    Lee
    private static LogonController CreateLogonController()
            {
                var controller = new LogonController();
                var response = Mock.Create<HttpResponseBase>();
                var httpContext = Mock.Create<HttpContextBase>();
                var routeData = new RouteData();
                var request = Mock.Create<HttpRequestBase>();
                var cookies = new HttpCookieCollection();
                var context = new ControllerContext(httpContext, routeData, Mock.Create<ControllerBase>());
                var browser = Mock.Create<HttpBrowserCapabilitiesBase>();
     
                response.Output = new StringWriter();
     
                Mock.Arrange(() => browser.IsMobileDevice).Returns(false);
     
                Mock.Arrange(() => request.Cookies).Returns(cookies);
                Mock.Arrange(() => request.ValidateInput());
                Mock.Arrange(() => request.UserAgent).Returns("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11");
                Mock.Arrange(() => request.Browser).Returns(browser);
     
                Mock.Arrange(() => response.Cookies).Returns(cookies);
     
                Mock.Arrange(() => httpContext.Request).Returns(request);
                Mock.Arrange(() => httpContext.Response).Returns(response);
     
                routeData.Values.Add("controller", "LogonController");
                routeData.Values.Add("action", "Index");
                controller.ControllerContext = context;
     
                return controller;
            }


    And here I am trying to use it to generate  the output of a view:

    public static class ApiExtensionMethods
    {
        public static string Render(this ViewResult result, Controller controller)
        {
            controller.ViewData.Model = result.Model;
            try
            {
                using (var sw = new StringWriter())
                {
                    var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, result.ViewName);
                    var context = new ViewContext(controller.ControllerContext, viewResult.View, result.ViewData, result.TempData, sw);
     
                    viewResult.View.Render(context, sw);
     
                    return sw.GetStringBuilder().ToString();
                }
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }
    }
  2. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 24 Apr 2013 Link to this post

    Hello Lee,

    Thank you for the sample code.

    However, I was not able to identify the issue. Is it possible to send us a compiling project containing the JustMock tests and the SUT (System Under Test). This will let us investigate the matter and accordingly provide s solution faster.

    If this is not doable, please give more information about the exception you are experiencing and what invokes it.

    Thank you for the understanding.

    Greetings,
    Kaloyan
    the Telerik team
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  3. DevCraft R3 2016 release webinar banner
  4. Lee Saunders
    Lee Saunders avatar
    20 posts
    Member since:
    Jul 2009

    Posted 24 Apr 2013 Link to this post

    Hello!

    No problem.  Here is a link to a zip file that contains the smallest possible MVC4 project.

    It contains just a single controller (HOME) with a single action (INDEX) and a test project that tries to render the view to html.

    the extension method that renders the view works great inside of the contoller when called by a browser, but by a test with a mocked up controller, not so much.

    To see others struggling with this change in MVC4 from MVC3, see:
    http://stackoverflow.com/questions/13348169/mvc-4-mocking-httpcontext-how-to-mock-displaymodeprovider

    Link to my example:
    http://www.leesaunders.net/examples/renderviewexample/renderviewexample.zip

    Thanks again,
    Lee
  5. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 29 Apr 2013 Link to this post

    Hello Lee,

    Thank you for the links.

    To avoid this exception you will need to have the Items property in HttpContextBase mocked as well. I added the following line in the CreateHomeController class and it did the job:
    Mock.Arrange(() => httpContext.Items).Returns(Mock.Create<IDictionary>());
    However, for the whole test to pass, you will need to further arrange some other dependencies.

    I hope this helps.

    Kind regards,
    Kaloyan
    the Telerik team
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  6. Lee Saunders
    Lee Saunders avatar
    20 posts
    Member since:
    Jul 2009

    Posted 01 May 2013 Link to this post

    Hello Kaloyan,

    You are right, that got me past the exception.  You are also correct that it just walked me into another exception.  Seems like either I need a lot more help getting this to "Green", or I need to look at other alternatives on how to get my "rendered" "view".

    Thanks.
    Lee
  7. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 07 May 2013 Link to this post

    Hello Lee,

    Sorry for the late reply.

    However, I will further investigate the issue and will try to provide possible solution(s). Please, let me contact you once again in the very near future.

    I hope this helps.

    All the best,
    Kaloyan
    the Telerik team
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  8. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 11 Nov 2013 Link to this post

    Hello Lee,

    With the release of JustMock 2013 Q3, we introduced the RecursiveLoose mocks. With them, I was able to find solution to the matter.

    I added several more arrangements inside your CreateHomeController() class, as follows (the new lines are marked with yellow):
    private static HomeController CreateHomeController()
    {
        var browser = Mock.Create<HttpBrowserCapabilitiesBase>();
        var response = Mock.Create<HttpResponseBase>();
        var httpContext = Mock.Create<HttpContextBase>();
        var request = Mock.Create<HttpRequestBase>();
        var engine = Mock.Create<IViewEngine>(); // Mocking IViewEngine
        var view = Mock.Create<IView>(); // Mocking IView
        var cookies = new HttpCookieCollection();
        var items = new ListDictionary();
     
        // Creating a ViewEngineResult, containing our mocks.
        var viewEngineResult = new ViewEngineResult(view, engine);
        // Arranging the FindPartialView to return our predefined viewEngineResult.
        Mock.Arrange(() => engine.FindPartialView(null, null, false)).IgnoreArguments().Returns(viewEngineResult);
        // Arranging the Render method of the IView mock to write inside the StringWriter.
        // We will assert on this later in the test.
        Mock.Arrange(() => view.Render(Arg.IsAny<ViewContext>(), Arg.IsAny<StringWriter>()))
            .DoInstead((ViewContext context1, StringWriter sw) => sw.Write("<h2>Index</h2>"));
        // Adding the mocked IViewEngine to the ViewEngines collection.
        ViewEngines.Engines.Add(engine);
     
        var controller = new HomeController();
        var routeData = new RouteData();
        var context = new ControllerContext(httpContext, routeData, Mock.Create<ControllerBase>());
     
        response.Output = new StringWriter();
     
        Mock.Arrange(() => browser.IsMobileDevice).Returns(false);
     
        Mock.Arrange(() => request.Cookies).Returns(cookies);
        Mock.Arrange(() => request.ValidateInput()).DoNothing();
        Mock.Arrange(() => request.UserAgent)
            .Returns(
                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11");
        Mock.Arrange(() => request.Browser).Returns(browser);
     
        Mock.Arrange(() => response.Cookies).Returns(cookies);
     
        Mock.Arrange(() => httpContext.Items).Returns(items);
         
        Mock.Arrange(() => httpContext.Request).Returns(request);
        Mock.Arrange(() => httpContext.Response).Returns(response);
     
        routeData.Values.Add("controller", "HomeController");
        routeData.Values.Add("action", "Index");
        controller.ControllerContext = context;
     
        return controller;
    }
    With the above changes, your test works as expected.

    As I understand the answer comes late, I deeply apologize for all the inconveniences caused and hope you find it helpful.

    Regards,
    Kaloyan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Back to Top
DevCraft R3 2016 release webinar banner