Note that there are some explanatory texts on larger screens.

plurals
  1. POIssues mocking the MVC ControllerContext request
    primarykey
    data
    text
    <p>I'm pretty new to testing and mocking and i am trying to write a test that will ensure that my validation logic is setting ModelState errors correctly. </p> <p>What I'm seeing is that the <em>controller.ControllerContext.HttpContext.Request</em> is set the first time I check it but every time after that the <em>Request</em> is null. </p> <p>This is causing a null reference exception in the <em>PopulateDictionary</em> method of the *ValueProviderDictionary * class in the MVC source because the request object is accessed multiple times in that method without ensuring the request is not null.</p> <p>I'm gluing together several techniques and helpers that I have found while researching how to overcome some of the issues I have run into thus far so at this point I'm a little unsure where I may have introduced the issue. </p> <p><strong>Am I using mock objects incorrectly here?</strong></p> <p><strong>Failing Test</strong></p> <pre><code>//Test public void Test_FooController_OnActionExecuting_ShouldMapStateToAFooModel() { //Arrange DataAccessFactoryMocks.MockAllDaos(); var controller = new FooController(); var testFormCollection = new NameValueCollection(); testFormCollection.Add("foo.CustomerID", "3"); testFormCollection.Add("_fooForm", SerializationUtils.Serialize(new FooModel())); var mockHttpContext = new MockHttpContext(controller, "POST", testFormCollection, null); //Accessor used to run the protected OnActionExecuting method in my controller var accessor = new FooControllerAccessor(controller); //Request is set, assertion passes Assert.IsNotNull(controller.ControllerContext.HttpContext.Request.Form); //Request is null when accessing the property a second time, assertion fails Assert.IsNotNull(controller.ControllerContext.HttpContext.Request.QueryString); //Act accessor.OnActionExecuting(new ActionExecutingContext(controller.ControllerContext, MockRepository.GenerateStub&lt;ActionDescriptor&gt;(), new Dictionary&lt;string, object&gt;())); //Assert Assert.That(controller.ModelState.IsValid == false); } </code></pre> <p><strong>Test Helper</strong></p> <pre><code>//Test helper to create httpcontext and set controller context accordingly public class MockHttpContext { public HttpContextBase HttpContext { get; private set; } public HttpRequestBase Request { get; private set; } public HttpResponseBase Response { get; private set; } public RouteData RouteData { get; private set; } public MockHttpContext(Controller onController) { //Setup the common context components and their relationships HttpContext = MockRepository.GenerateMock&lt;HttpContextBase&gt;(); Request = MockRepository.GenerateMock&lt;HttpRequestBase&gt;(); Response = MockRepository.GenerateMock&lt;HttpResponseBase&gt;(); //Setup the context, request, response relationship HttpContext.Stub(c =&gt; c.Request).Return(Request); HttpContext.Stub(c =&gt; c.Response).Return(Response); Request.Stub(r =&gt; r.Cookies).Return(new HttpCookieCollection()); Response.Stub(r =&gt; r.Cookies).Return(new HttpCookieCollection()); Request.Stub(r =&gt; r.QueryString).Return(new NameValueCollection()); Request.Stub(r =&gt; r.Form).Return(new NameValueCollection()); //Apply the context to the suppplied controller var rc = new RequestContext(HttpContext, new RouteData()); onController.ControllerContext = new ControllerContext(rc, onController); } public MockHttpContext(Controller onController, string httpRequestType, NameValueCollection form, NameValueCollection querystring) { //Setup the common context components and their relationships HttpContext = MockRepository.GenerateMock&lt;HttpContextBase&gt;(); Request = MockRepository.GenerateMock&lt;HttpRequestBase&gt;(); Response = MockRepository.GenerateMock&lt;HttpResponseBase&gt;(); //Setup request type based on parameter value Request.Stub(r =&gt; r.RequestType).Return(httpRequestType); //Setup the context, request, response relationship HttpContext.Stub(c =&gt; c.Request).Return(Request); HttpContext.Stub(c =&gt; c.Response).Return(Response); Request.Stub(r =&gt; r.Cookies).Return(new HttpCookieCollection()); Response.Stub(r =&gt; r.Cookies).Return(new HttpCookieCollection()); Request.Stub(r =&gt; r.QueryString).Return(querystring); Request.Stub(r =&gt; r.Form).Return(form); //Apply the context to the suppplied controller var rc = new RequestContext(HttpContext, new RouteData()); onController.ControllerContext = new ControllerContext(rc, onController); } } </code></pre> <p><strong>Working Test using MvcContrib.TestHelper</strong></p> <pre><code> public void Test_FooController_OnActionExecuting_ShouldMapStateToAFooModel() { //Arrange DataAccessFactoryMocks.MockAllDaos(); TestControllerBuilder builder = new TestControllerBuilder(); builder.Form.Add("fooModel.CustomerID", "3"); builder.HttpContext.Request.Stub(r =&gt; r.RequestType).Return("POST"); FooController controller = builder.CreateController&lt;FooController&gt;(); var accessor = new FooControllerAccessor(controller); //Act accessor.OnActionExecuting(new ActionExecutingContext(controller.ControllerContext, MockRepository.GenerateStub&lt;ActionDescriptor&gt;(), new Dictionary&lt;string, object&gt;())); //Assert Assert.IsFalse(controller.ModelState.IsValid); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload