I have a unit test fixture in which I'm trying to test a ControllerAction on an ASP.NET MVC controller that's used for membership functions on a web app. I'm trying to mock the HttpContext for the tests. The ControllerAction under test actually sets properties on the HttpContext, such as Session values, Response.Cookies values, etc. This isn't all of the code, but here is a rough sample of the test that I'm trying to get to run:
[Test]
public void ValidRegistrationDataSuccessfullyCreatesAndRegistersUser()
{
var context = new Mock<HttpContextBase>() {DefaultValue = DefaultValue.Mock};
context.SetupAllProperties();
var provider = new Mock<MembershipProvider>(new object[] {context.Object});
var controller = new AccountController(context.Object, provider.Object);
// This just sets up a local FormCollection object with valid user data
// in it to use to attempt the registration
InitializeValidFormData();
ActionResult result = controller.Register(_registrationData);
Assert.IsInstanceOfType(typeof(ViewResult), result);
// Here is where I'd like to attempt to do Assertions against properties
// of the HttpContext, like ensuring that a Session object called "User"
// exists, and new auth cookie exists on the Response.Cookies collection.
// So far I've been unable to successfully check the values of those properties.
// I've been unsuccessful in getting those properties setup correctly on my
// mock object so that my ControllerAction can actually *set* their values,
// and that I can make assertions on them afterwards. The above code actually
// generates a StackOverflowException (which I've reported) on the
// context.SetupAllProperties() call. What am I doing wrong, or what do I need
// to do to be able to set and assert on those context properties?
}
Not sure what I'm doing wrong, but I'd love it if someone could point me in the right direction and show me how to setup this mock HttpContextBase object such that my controller can actually set values on its properties, and I can make assertions on those properties to ensure that my ControllerAction is doing what I need it to.
Am I approaching this the wrong way? I know that MVC Controllers have a ControllerContext that I can use to set values for Session, etc, but I can't figure out how something like that could be mocked without injecting it. Is there some way of doing that instead? (I also need to be able to pass the context in to my MembershipProvider too) Would that be a better approach?
Thanks.