Tuesday 16 February 2010

MVC Mock helper class


public static class MvcMockHelpers
{
public static HttpContextBase FakeHttpContext()
{
var context = new Mock();
var request = new Mock();
var response = new Mock();
var session = new Mock();
var server = new Mock();

context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
context.Setup(ctx => ctx.Server).Returns(server.Object);
context.SetupGet(ctx => ctx.User.Identity.Name).Returns("TestUser");

return context.Object;
}

public static HttpContextBase FakeHttpContext(string address)
{
HttpContextBase context = FakeHttpContext();
context.Request.SetupRequestUrl(address);
return context;
}

public static void SetFakeControllerContext(this ControllerBase controller)
{
var httpContext = FakeHttpContext();
ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
}

public static void SetHttpMethodResult(this HttpRequestBase request, string httpMethod)
{
Mock.Get(request)
.Setup(req => req.HttpMethod)
.Returns(httpMethod);
}

public static void SetupRequestUrl(this HttpRequestBase request, string address)
{
if (address == null)
{
throw new ArgumentNullException("address");
}

if (!address.StartsWith("~/", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\".");
}

var mock = Mock.Get(request);

mock.Setup(req => req.QueryString)
.Returns(GetQueryStringParameters(address));
mock.Setup(req => req.AppRelativeCurrentExecutionFilePath)
.Returns(GetUrlFileName(address));
mock.Setup(req => req.PathInfo)
.Returns(string.Empty);
}

private static string GetUrlFileName(string url)
{
if (url.Contains("?"))
{
return url.Substring(0, url.IndexOf("?", StringComparison.OrdinalIgnoreCase));
}
else
{
return url;
}
}

private static NameValueCollection GetQueryStringParameters(string url)
{
if (url.Contains("?"))
{
NameValueCollection parameters = new NameValueCollection();

string[] parts = url.Split("?".ToCharArray());
string[] keys = parts[1].Split("&".ToCharArray());

foreach (string key in keys)
{
string[] part = key.Split("=".ToCharArray());
parameters.Add(part[0], part[1]);
}

return parameters;
}
else
{
return null;
}
}
}