Last Updated: February 25, 2016
·
5.102K
· purekrome

Common ASP.NET MVC controller mocking scenarios

I don't know how many times I keep needing to mock out parts of an ASP.NET MVC's controller context. In fact - it's a requirement if you're doing any ASP.NET MVC Web Application.

That's kewl! So lets look at some common helpers I use in my unit tests.

FYI: I'm using Moq as my mock testing framework

Overall Info.

Everything comes back to the ControllerContext property, on a Controller instance. As such, I like to see if we can pass as much stuff into a single method which returns a Mocked instance of this.

public static Mock<ControllerContext> MockControllerContext(Mock<HttpSessionStateBase> mockSessionStateBase = null)
{
    var mockControllContext = new Mock<ControllerContext>();
    if (mockSessionStateBase == null)
    {
        mockSessionStateBase = MockSessionStateBase();
    }

    mockControllContext.Setup(x => x.HttpContext.Session).Returns(mockSessionStateBase.Object);

    return mockControllContext;
}

Scenario: Referencing the Session.

Problem:

public RedirectResult RedirectToAuthenticationProvider(RedirectToAuthenticationProviderInputModel inputModel)
{
    // Which provider are we after?
    var settings = AuthenticationServiceSettingsFactory.GetAuthenticateServiceSettings(inputModel.ProviderKey);

    // We need to remember the state for some XSS protection.
    Session[SessionStateKey] = Guid.NewGuid();
    settings.State = Session[SessionStateKey].ToString();

    // Grab the Uri we need redirect to.
    var uri = _authenticationService.RedirectToAuthenticationProvider(settings);

    // Redirect!
    return Redirect(uri.AbsoluteUri);
}

Setup:

We can have multiple Session Key/Values in a single Context. As such, this method can be called multiple times. If you provide a specific key/value, then we set it up, with that. Otherwise, accept anything :)

public static Mock<HttpSessionStateBase> MockSessionStateBase(string sessionStateKey = null,
                                                                object sessionStateValue = null)
{
    var mockSessionStateBase = new Mock<HttpSessionStateBase>();
    if (string.IsNullOrEmpty(sessionStateKey) ||
        sessionStateValue == null)
    {
        mockSessionStateBase.Setup(x => x[It.IsAny<string>()]).Returns("some-fake-state");
    }
    else
    {
        mockSessionStateBase.Setup(x => x[sessionStateKey]).Returns(sessionStateValue);
    }

    return mockSessionStateBase;
}

Usage:

var mockSession = ControllerMocks.MockSessionStateBase();
var authenticationController = new AuthenticationController(authenticationService)
                                    {
                                        ControllerContext =
                                            ControllerMocks.MockControllerContext(mockSession).Object
                                    };