Thursday, December 13, 2007

More Mocking of HttpContext for MVC

I was actually preparing this for a comment to my last post in answer to chris7's comment. But it got long. You know!

Chris7 asked if it was possible to abstract out the Record/Playback syntax in the example to make the code clearer. And you can of course do that and put the Replay call into the MockContextFactory like this:

protected IHttpContext MockContextFactory(string url)
{
IHttpContext httpContext = mockery.Stub<IHttpContext>();
IHttpRequest httpRequest = mockery.Stub<IHttpRequest>();
SetupResult.For(httpRequest.AppRelativeCurrentExecutionFilePath).Return("~" + url);
SetupResult.For(httpContext.Request).Return(httpRequest);
mockery.Replay(httpRequest);
mockery.Replay(httpContext);
return httpContext;
}


The code in the test method would then look this way:



[Test]
public void WorldDetailsRouteExists1()
{
IHttpContext httpContext = MockContextFactory("/World/Details/9/3");
RouteData routeData = routes.GetRouteData(httpContext);
Assert.IsNotNull(routeData, "There is a route to the URL");
Assert.AreEqual("World", routeData.Values["controller"], "We are using the world controller");
Assert.AreEqual("Details", routeData.Values["action"], "With the details action");
Assert.AreEqual("9", routeData.Values["x"], "And the correct x");
Assert.AreEqual("3", routeData.Values["y"], "And the correct y");
mockery.VerifyAll();
}


I actually chose the Record/Playback model as I find it nicer to look at than the other syntax. But I guess it is a matter of taste. In this example it is probably not obvious why I prefer that syntax, but for more involved mocking scenarios it makes it easier to see what is record and what is playback.



Phil Haacked also commented with a post of his own describing how to the same thing using extension methods instead. I encourage you to look at that as well to see yet another way of doing it.



kick it on DotNetKicks.com

No comments: