I am having trouble unit testing some of the methods in my Orchestrator class. Basically, my troubles centre around mocking the HttpRequest object. At the moment, my class looks like this:
public HttpRequestWrapper Request { get; set; }
public AccountControllerOrchestrator(...other parameters..., HttpRequestWrapper request)
{
Request = request;
}
The problem is creating a seam against which I can mock. So, I need to be able to mock that request parameter. Here is what I have tried...
First, I have a factory, which has the duty of setting the HttpContext:
public class HttpContextFactory
{
private static HttpContextBase m_context;
public static HttpContextBase Current
{
get
{
if (m_context != null)
return m_context;
if (HttpContext.Current == null)
throw new InvalidOperationException("HttpContext not available");
return new HttpContextWrapper(HttpContext.Current);
}
}
public static void SetCurrentContext(HttpContextBase context)
{
m_context = context;
}
}
Then, I have a method which creates a HttpContextBase:
private HttpContextBase GetMockedHttpContext()
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
var user = new Mock<IPrincipal>();
var identity = new Mock<IIdentity>();
var urlHelper = new Mock<UrlHelper>();
//RouteConfig.RegisterRoutes(RouteTable.Routes);
var requestContext = new Mock<RequestContext>();
requestContext.Setup(x => x.HttpContext).Returns(context.Object);
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.Setup(ctx => ctx.User).Returns(user.Object);
user.Setup(ctx => ctx.Identity).Returns(identity.Object);
identity.Setup(id => id.IsAuthenticated).Returns(true);
identity.Setup(id => id.Name).Returns("test");
request.Setup(req => req.Url).Returns(new Uri(ConfigurationManager.AppSettings["SiteUrl"]));
request.Setup(req => req.ApplicationPath).Returns(Path.AltDirectorySeparatorChar.ToString);
request.Setup(req => req.RequestContext).Returns(requestContext.Object);
request.Setup(req => req.UrlReferrer).Returns(new Uri(@"http://localhost:3538/"));
requestContext.Setup(x => x.RouteData).Returns(new RouteData());
request.SetupGet(req => req.Headers).Returns(new NameValueCollection());
return context.Object;
}
That came from this answer https://stackoverflow.com/a/9624433/540156
After setting the context using the factory, unfortunately, the following line does not work because the AccountControllerOrchestrator's constructor parameter is HttpRequestWrapper and that class won't accept an object of type HttpRequestBase (see last parameter).
_accountControllerOrchestrator = new AccountControllerOrchestrator(_loggerMock.Object, _membershipServiceMock.Object, _orderManagementServiceMock.Object, _stateServiceMock.Object, new HttpRequestWrapper(HttpContextFactory.Current.Request));
So, any idea how I can solve this?