Search code examples
c#asp.net-mvcunit-testingmoqrazorgenerator

How to unit test Request.IsAuthenticated of razor view


I am using RazorGenerator to test the views. But when I try to mock the Request I can see the IsAuthenticated property getting populated but the view when rendered does not return the desired HTML.

_Login.cshtml

@using System.Security.Claims
@if (Request.IsAuthenticated)

{

    <text>
        <ul class="nav navbar-nav navbar-right">
            <li>
                @Html.ActionLink(@welcome, null, null, null, new { id = "test1" })
            </li>
            <li>
                @Html.ActionLink("Sign out", "SignOut", "Account")
            </li>
        </ul>
    </text>
    }else
    {
        <ul class="nav navbar-nav navbar-right">
            <li>
                @Html.ActionLink("Log in", "SignIn", "Account", null, new {id = "test2" })
            </li>
        </ul>
    }

I have the following test case which always gives me the html from else condition.

public void test23()
        {
            v_Request.SetupGet(x => x.IsAuthenticated).Returns(true);
            v_Context.SetupGet(x => x.Request).Returns(v_Request.Object);
            v_ControllerContext = new Mock<ControllerContext>(
                v_Context.Object,
                new RouteData(),
                v_Controller.Object);
            v_ControllerContext.Setup(x => x.HttpContext).Returns(v_Context.Object);
            v_ViewContext = new Mock<ViewContext>(
                v_ControllerContext.Object,
                new Mock<IView>().Object,
                null,
                new TempDataDictionary(),
                null);
            _Views_Shared__Login_cshtml view = new _Views_Shared__Login_cshtml();

            view.ViewContext = new ViewContext(v_ControllerContext.Object, new Mock<IView>().Object, view.ViewData, new TempDataDictionary(), new Mock<TextWriter>().Object);

            HtmlDocument doc = view.RenderAsHtml();
        }

_Views_Shared__Login_cshtml is the class generated by RazorGenerator. Any leads..?


Solution

  • If you want to unit test the View you can consider it a hint asking for a refactoring in your code.

    Views are very rarely tested since they should not have too much functionality. Tests should be focused in the code that generates it.

    As you says, the view is from a parent one. You could create a filter:

    public class MyAuthFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ViewBag=filterContext.HttpContext.Request.IsAuthenticated;
        }
    }
    

    Register it:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyAuthFilterAttribute ());
    }
    

    And you will have the ViewBag filled allways