1

I am doing unit tests using NUnit and Moq. I tried this example that checks whether a session object called Role exists. If not, it creates it, and returns an object of type Role.

protected Role GetRole()
    {
        if (Session["Role"] == null)
        {
            Session["Role"] = new Role();
        }

        return Session["Role"] as Role;
    }

Then I use it in the Index action:

public ActionResult Index()
    {
        var roles = GetRole();
        roles.RoleName = "Test";
        return View();
    }

And this is my test:

[Test]
    public void TestMethod1()
    {
        var contextMock = new Mock<ControllerContext>();
        var mockHttpContext = new Mock<HttpContextBase>();
        var session = new Mock<HttpSessionStateBase>();

        mockHttpContext.Setup(ctx => ctx.Session).Returns(session.Object);
        contextMock.Setup(ctx => ctx.HttpContext).Returns(mockHttpContext.Object);

        contextMock.Setup(p => p.HttpContext.Session["Role"]).Returns(new Role
                                                                      {
                                                                          RoleId = 1,
                                                                          RoleName = "Test"
                                                                      });
        var homeController = new HomeController();
        homeController.ControllerContext = contextMock.Object;
        var indexView = homeController.Index();
        Assert.IsNotNull(indexView);
    }

It runs successfully. But when I check the code coverage, it gives me that the Session["Role"] = new Role(); part is not covered by the test code. So I made another test. There I don't setup the session variable Role:

[Test]
    public void TestMethod2()
    {
        var contextMock = new Mock<ControllerContext>();
        var mockHttpContext = new Mock<HttpContextBase>();
        var session = new Mock<HttpSessionStateBase>();

        mockHttpContext.Setup(ctx => ctx.Session).Returns(session.Object);
        contextMock.Setup(ctx => ctx.HttpContext).Returns(mockHttpContext.Object);
        var homeController = new HomeController();
        homeController.ControllerContext = contextMock.Object;
        var indexView = homeController.Index();

        Assert.IsNotNull(indexView);
        Assert.IsNull(homeController.ControllerContext.HttpContext.Session["Role"]);
    }

But it fails - it gives System.NullReferenceException : Object reference not set to an instance of an object because of the roles.RoleName = "Test"; row. How to make it run? Thank you in advance!

1 Answer 1

2

The problem you have is that in the second test Session["Role"] will never return anything as it's a mocked object set up to always return null. One possible workaround is to change your GetRole function to this and adjust your tests:

protected Role GetRole()
{
    var role = Session["Role"] as Role;

    if (role == null)
    {
        role = new Role();
        Session["Role"] = role;
    }

    return role;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.