How do I mock a page request for a .net MVC page?
Asked
Active
Viewed 5,521 times
3 Answers
14
Using RhinoMocks:
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
httpContext.Expect( c => c.Request ).Return( httpRequest ).Repeat.Any();
... set up expectations on request...
var controller = new MyController();
controller.ControllerContext = new ControllerContext( httpContext,
new RouteData(),
controller );
...invoke action, check assertions...
httpContext.VerifyAllExpectations();
httpRequest.VerifyAllExpectations();

tvanfosson
- 524,688
- 99
- 697
- 795
12
Using Moq:
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.Setup(x => x.ApplicationPath).Returns("/");
request.Setup(x => x.Url).Returns(new Uri("http://localhost/home"));
request.Setup(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new YourController();
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);

eu-ge-ne
- 28,023
- 6
- 71
- 62
11
Manually (because I hate Mocking frameworks that require 8 lines of setup per test)
// in some common location, only once
public class MockHttpContext : HttpContextBase
{
public MockHttpRequest m_request = new MockHttpRequest();
public MockHttpResponse m_response = new MockHttpResponse();
public override HttpRequestBase Request
{ get { return m_request; } }
public override HttpResponseBase Response
{ get { return m_response; } }
}
public class MockHttpRequest : HttpRequestBase
{
// override whatever bits you want (eg cookies)
}
public class MockHttpResponse : HttpResponseBase
{
// override whatever bits you want (eg cookies)
}
// in your specific test
controller = new YourController {
ControllerContext = new ControllerContext { HttpContext = new MockHttpContext() }
};

Orion Edwards
- 121,657
- 64
- 239
- 328
-
I like this. This is much easier to understand than mocking. Any reason why the m_request and m_response are public? – Arman Bimatov May 14 '14 at 06:18
-
1because it's a fake object designed to make testing things easier. Making those private would just mean if I wanted to change them (and sometimes you might) I'd have to have a property, etc, etc. Some rules such as implementation hiding are actively harmful in this kind of environment – Orion Edwards May 14 '14 at 23:58
-
I realized why they're public right after I asked the question. Neither Request nor Response don't have setters, because that's how it is in the HttpContextBase. So if I need to mutate the request and response from my unit tests, I need them public. – Arman Bimatov May 15 '14 at 15:36
-
1@OrionEdwards, this is the only answer I could find that explained how to do this simple think without mocking frameworks. It had to be built in to ASP.NET MVC, as unit tests are one of the main advantages this framework brings with it. And it is so easy. It's just a shame almost no one talks about it. Thanks a lot!! – Mohoch Oct 29 '14 at 15:03