<p>So the controller context depends on some asp.net internals. What are some ways to cleanly mock these up for unit tests? Seems like its very easy to clog up tests with tons of setup when I only need, for example, Request.HttpMethod to return "GET".</p>

<p>I've seen some examples/helpers out on the nets, but some are dated. Figured this would be a good place to keep the latest and greatest.</p>

<p>I'm using latest version of rhino mocks</p>

[{'answer_id': 32672, 'author': 'Haacked', 'author_id': 598, 'author_profile': 'https://Stackoverflow.com/users/598', 'pm_score': 7, 'selected': True, 'text': '<p>Using MoQ it looks something like this:</p>\n\n<pre><code>var request = new Mock&lt;HttpRequestBase&gt;();\nrequest.Expect(r =&gt; r.HttpMethod).Returns("GET");\nvar mockHttpContext = new Mock&lt;HttpContextBase&gt;();\nmockHttpContext.Expect(c =&gt; c.Request).Returns(request.Object);\nvar controllerContext = new ControllerContext(mockHttpContext.Object\n, new RouteData(), new Mock&lt;ControllerBase&gt;().Object);\n</code></pre>\n\n<p>I think the Rhino Mocks syntax is similar.</p>\n'}, {'answer_id': 33597, 'author': 'Matt Hinze', 'author_id': 2676, 'author_profile': 'https://Stackoverflow.com/users/2676', 'pm_score': 0, 'selected': False, 'text': '<p>I find that long mocking procedure to be too much friction.</p>\n\n<p>The best way we have found - using ASP.NET MVC on a real project - is to abstract the HttpContext to an IWebContext interface that simply passes through. Then you can mock the IWebContext with no pain.</p>\n\n<p>Here is an <a href="http://code.google.com/p/tarantino/source/browse/trunk/src/Tarantino.Core/Commons/Services/Web/IWebContext.cs" rel="nofollow noreferrer">example</a></p>\n'}, {'answer_id': 33798, 'author': "Dane O'Connor", 'author_id': 1946, 'author_profile': 'https://Stackoverflow.com/users/1946', 'pm_score': 4, 'selected': False, 'text': '<p>Here\'s a snippet from Jason\'s link. Its the same as Phil\'s method but uses rhino. </p>\n\n<p><em>Note: mockHttpContext.Request is stubbed to return mockRequest <strong>before</strong> mockRequest\'s internals are stubbed out. I believe this order is required.</em></p>\n\n<pre><code>// create a fake web context\nvar mockHttpContext = MockRepository.GenerateMock&lt;HttpContextBase&gt;();\nvar mockRequest = MockRepository.GenerateMock&lt;HttpRequestBase&gt;();\nmockHttpContext.Stub(x =&gt; x.Request).Return(mockRequest);\n\n// tell the mock to return "GET" when HttpMethod is called\nmockRequest.Stub(x =&gt; x.HttpMethod).Return("GET");            \n\nvar controller = new AccountController();\n\n// assign the fake context\nvar context = new ControllerContext(mockHttpContext, \n                  new RouteData(), \n                  controller);\ncontroller.ControllerContext = context;\n\n// act\n...\n</code></pre>\n'}, {'answer_id': 220113, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': '<p>i\'ve finished with this spec</p>\n\n<pre><code>public abstract class Specification &lt;C&gt; where C: Controller\n{\n    protected C controller;\n\n    HttpContextBase mockHttpContext;\n    HttpRequestBase mockRequest;\n\n    protected Exception ExceptionThrown { get; private set; }\n\n    [SetUp]\n    public void Setup()\n    {\n        mockHttpContext = MockRepository.GenerateMock&lt;HttpContextBase&gt;();\n        mockRequest = MockRepository.GenerateMock&lt;HttpRequestBase&gt;();\n\n        mockHttpContext.Stub(x =&gt; x.Request).Return(mockRequest);\n        mockRequest.Stub(x =&gt; x.HttpMethod).Return("GET");\n\n\n        EstablishContext();\n        SetHttpContext();\n\n        try\n        {\n            When();\n        }\n        catch (Exception exc)\n        {\n            ExceptionThrown = exc;\n        }\n    }\n\n    protected void SetHttpContext()\n    {\n        var context = new ControllerContext(mockHttpContext, new RouteData(), controller);\n        controller.ControllerContext = context;\n    }\n\n    protected T Mock&lt;T&gt;() where T: class\n    {\n        return MockRepository.GenerateMock&lt;T&gt;();\n    }\n\n    protected abstract void EstablishContext();\n    protected abstract void When();\n\n    [TearDown]\n    public virtual void TearDown()\n    {\n    }\n} \n</code></pre>\n\n<p>and the juice is here </p>\n\n<pre><code>[TestFixture]\npublic class When_invoking_ManageUsersControllers_Update :Specification   &lt;ManageUsersController&gt;\n{\n    private IUserRepository userRepository;\n    FormCollection form;\n\n    ActionResult result;\n    User retUser;\n\n    protected override void EstablishContext()\n    {\n        userRepository = Mock&lt;IUserRepository&gt;();\n        controller = new ManageUsersController(userRepository);\n\n        retUser = new User();\n        userRepository.Expect(x =&gt; x.GetById(5)).Return(retUser);\n        userRepository.Expect(x =&gt; x.Update(retUser));\n\n        form = new FormCollection();\n        form["IdUser"] = 5.ToString();\n        form["Name"] = 5.ToString();\n        form["Surename"] = 5.ToString();\n        form["Login"] = 5.ToString();\n        form["Password"] = 5.ToString();\n    }\n\n    protected override void When()\n    {\n        result = controller.Edit(5, form);\n    }\n\n    [Test]\n    public void is_retrieved_before_update_original_user()\n    {\n        userRepository.AssertWasCalled(x =&gt; x.GetById(5));\n        userRepository.AssertWasCalled(x =&gt; x.Update(retUser));\n    }\n}\n</code></pre>\n\n<p>enjoy</p>\n'}, {'answer_id': 491798, 'author': 'RoyOsherove', 'author_id': 18426, 'author_profile': 'https://Stackoverflow.com/users/18426', 'pm_score': 3, 'selected': False, 'text': '<p>Or you can do this with Typemock Isolator with no need to send in a fake controller at all:</p>\n\n<pre><code>Isolate.WhenCalled(()=&gt;HttpContext.Request.HttpMethod).WillReturn("Get");\n</code></pre>\n'}, {'answer_id': 1959077, 'author': 'Gabe Moothart', 'author_id': 13356, 'author_profile': 'https://Stackoverflow.com/users/13356', 'pm_score': 3, 'selected': False, 'text': '<p>The procedure for this seems to have changed slightly in MVC2 (I\'m using RC1). Phil Haack\'s solution doesn\'t work for me if the action requires a specific method (<code>[HttpPost]</code>, <code>[HttpGet]</code>). Spelunking around in Reflector, it looks like the method for verifying these attributes has changed. MVC now checks <code>request.Headers</code>, <code>request.Form</code>, and <code>request.QueryString</code> for a <code>X-HTTP-Method-Override</code> value.</p>\n\n<p>If you add mocks for these properties, it works:</p>\n\n<pre><code>var request = new Mock&lt;HttpRequestBase&gt;();\nrequest.Setup(r =&gt; r.HttpMethod).Returns("POST");\nrequest.Setup(r =&gt; r.Headers).Returns(new NameValueCollection());\nrequest.Setup(r =&gt; r.Form).Returns(new NameValueCollection());\nrequest.Setup(r =&gt; r.QueryString).Returns(new NameValueCollection());\n\nvar mockHttpContext = new Mock&lt;HttpContextBase&gt;();\nmockHttpContext.Expect(c =&gt; c.Request).Returns(request.Object);\nvar controllerContext = new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock&lt;ControllerBase&gt;().Object);\n</code></pre>\n'}, {'answer_id': 15016922, 'author': 'Maksym Kozlenko', 'author_id': 171847, 'author_profile': 'https://Stackoverflow.com/users/171847', 'pm_score': 5, 'selected': False, 'text': '<p>Here is a sample unit test class using MsTest and Moq which mocks HttpRequest and HttpResponse objects. (.NET 4.0, ASP.NET MVC 3.0 )</p>\n\n<p>Controller action get value from request and sets http header in response objects. Other http context objects could be mocked up in similar way</p>\n\n<pre><code>[TestClass]\npublic class MyControllerTest\n{\n    protected Mock&lt;HttpContextBase&gt; HttpContextBaseMock;\n    protected Mock&lt;HttpRequestBase&gt; HttpRequestMock;\n    protected Mock&lt;HttpResponseBase&gt; HttpResponseMock;\n\n    [TestInitialize]\n    public void TestInitialize()\n    {\n        HttpContextBaseMock = new Mock&lt;HttpContextBase&gt;();\n        HttpRequestMock = new Mock&lt;HttpRequestBase&gt;();\n        HttpResponseMock = new Mock&lt;HttpResponseBase&gt;();\n        HttpContextBaseMock.SetupGet(x =&gt; x.Request).Returns(HttpRequestMock.Object);\n        HttpContextBaseMock.SetupGet(x =&gt; x.Response).Returns(HttpResponseMock.Object);\n    }\n\n    protected MyController SetupController()\n    {\n        var routes = new RouteCollection();\n        var controller = new MyController();\n        controller.ControllerContext = new ControllerContext(HttpContextBaseMock.Object, new RouteData(), controller);\n        controller.Url = new UrlHelper(new RequestContext(HttpContextBaseMock.Object, new RouteData()), routes);\n        return controller;\n    }\n\n    [TestMethod]\n    public void IndexTest()\n    {\n        HttpRequestMock.Setup(x =&gt; x["x"]).Returns("1");\n        HttpResponseMock.Setup(x =&gt; x.AddHeader("name", "value"));\n\n        var controller = SetupController();\n        var result = controller.Index();\n        Assert.AreEqual("1", result.Content);\n\n        HttpRequestMock.VerifyAll();\n        HttpResponseMock.VerifyAll();\n    }\n}\n\npublic class MyController : Controller\n{\n    public ContentResult Index()\n    {\n        var x = Request["x"];\n        Response.AddHeader("name", "value");\n        return Content(x);\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/32640', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1946/']