Unit test, which uses the identifier in the mvc regular controller (and not the web-api controller)

I have a method in the mvc regular controller that checks the user id to see which page the user should be directed to. However, building a unit test with respect to this method results in an “object reference not set” error, because the user is always null when the method is run as part of the test.

public ActionResult Index()
        {
            if (User.Identity.IsAuthenticated)
            {
                if (User.IsInRole("Administrator"))
                {
                    return RedirectToAction("Console");
                }

                ViewBag.StatusMessage = "You are logged in but do not have sufficient permissions.";
            }
            else
            {
                ViewBag.StatusMessage = "Please log in";
            }

            return View();
        }

I have tried various solutions suggested in Writing unit test for methods that use User.Identity.Name in the ASP.NET web interface . Usually they use the following inside the unit test body:

var identity = new GenericIdentity("UserName");
Thread.CurrentPrincipal = new GenericPrincipal(identity, null);
var controller = new FooController(); 

, ApiController, WebApi, , , - mvc. User . ?

+4
2

, WebAPI, , Unit Test ApiController User.

, ASP.NET MVC, , . , / , , , , , .

, . , .

//System Under Test - i.e to test User
public class SutController : Controller
{
    public string Get() {
        return User.Identity.Name;
    }
}

public class TestableControllerContext : ControllerContext {
    public TestableHttpContext TestableHttpContext { get; set; }
}

public class TestableHttpContext : HttpContextBase {
    public override IPrincipal User { get; set; }
}

[TestMethod]
public void IndexNoneMoq()
{
    var identity = new GenericIdentity("tugberk");
    var controller = new SutController();

    var controllerContext = new TestableControllerContext();
    var principal = new GenericPrincipal(identity, null);
    var testableHttpContext = new TestableHttpContext
    {
        User = principal
    };

    controllerContext.HttpContext = testableHttpContext;
    controller.ControllerContext = controllerContext;

    Assert.AreEqual(controller.Get(), identity.Name);
}

Mocking/Isolation i.e Moq

[TestMethod]
public void IndexMoq()
{
    var identity = new GenericIdentity("tugberk");          
    var controller = new SutController();

    var controllerContext = new Mock<ControllerContext>();
    var principal = new Mock<IPrincipal>();
    principal.Setup(p => p.IsInRole("Administrator")).Returns(true);
    principal.SetupGet(x => x.Identity.Name).Returns("tugberk");
    controllerContext.SetupGet(x => x.HttpContext.User).Returns(principal.Object);
    controller.ControllerContext = controllerContext.Object;

    Assert.AreEqual(controller.Get(), identity.Name);
}

: , ASP.NET WebAPI MVC (AFAIK), , .

+7

, MVC Unit test.

[TestMethod]
public void IndexManualMoq()
{
.
.
.
    var controller = new SutController();
    controller.ControllerContext = new ControllerContext
    {
        HttpContext = new MockHttpContext
        {
            User = new GenericPrincipal(new GenericIdentity("JDoe"), null)
        }
    };
.
.
.
}

private class MockHttpContext : HttpContextBase
{
    public override IPrincipal User { get; set; }
}
+2

Source: https://habr.com/ru/post/1545445/


All Articles