Share via


Testing response status

Question

Wednesday, February 18, 2009 7:26 AM

 This is my first post here so.. Hi everyone.

First of all, I'm right now mainly Rails developer but earlier I used C, C++, Java (j2ee, spring etc), PHP and even Cobol. I'm new to ASP and I must say that it has terrible documentation. Please undeceive me but does pure asp, asp mvc (yes I know that is new project) has someting like documentation with examples? I mean something like ruby/rails/java doc (more on gotapi.com). Till now I found only quite nice MVC Contrib: http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=Documentation at least there are examples. I know that there is a reflector but it's not enough. Ok but this is not what I wanted to ask.

Could you tell me how can I test status code form response? First I had problem testing anything becouse I used HttpContext.GetGlobalResourceObject in the controller. I found here altnetuk with tests and I used HttpContextBase Mock and I wrote something like this:

 

HomeController controller = new HomeController();
controller.ControllerContext = new ControllerContext(new RequestContext(HttpContextBaseMock.New(), new RouteData()), controller);

controller.Index();
string status = controller.Response.Status;
Assert.AreEqual<string>("200 OK", status);

  

But it fails because controller.Response.Status is empty. I can't even test it why because test in debug mode don't work (which is popular bug as I read: The breakpoint will not currently be hit. No symbols have been loaded for this document.)

Of course I debug my application (not test) I was able to see that Response object has Status set correctly. I assume that it is because Mock give me empty object not real conversation between application at the server and my tests. 

I'm using asp mvc rc, moq and any testing framework (I can manage gallio/mbunit, nunit or xunit). Btw nunit has nice doc with examples, mbunit not so bad, but moq.. no examples.. api sometimes is not enough.

Thanks in advance for your help.

All replies (6)

Friday, February 20, 2009 1:25 PM âś…Answered

If your controller action method returns View(), the only thing you should check is that your controller action method returned an object of type ViewResult.  If your controller action method returns View("About"), you need to check that the returned object is of type ViewResult and that the selected view name is "About".  Your unit test should not be trying to execute the result; it should assume that the ViewResult type works as intended.

The central concept here is that you should test only code that you write.  Since the ViewResult type was written by the MVC team, the MVC team is responsible for writing the unit tests that verify proper behavior of that type.

Please let us know if this does not clarify the issue. :)


Wednesday, February 18, 2009 8:04 AM

Hello.

I believe that you'll need to mock the classes defined on the abstraction assembly which ships swith MVC (Since the MVC classes are coded around those abstract classes, you should be able to mock them easily)


Wednesday, February 18, 2009 8:15 AM

Hi,

following on from Luis answer this is the test for the HttpUnauthorizedResult from the MVC source and may help you get started.

 

        [TestMethod]
        public void ExecuteResult() {
            // Arrange

            Mock<ControllerContext> mockControllerContext = new Mock<ControllerContext>(MockBehavior.Strict);
            mockControllerContext.ExpectSet(c => c.HttpContext.Response.StatusCode, 401).Verifiable();

            HttpUnauthorizedResult result = new HttpUnauthorizedResult();

            // Act

            result.ExecuteResult(mockControllerContext.Object);

            // Assert

            mockControllerContext.Verify();
        }

Kind regards,

Paul


Thursday, February 19, 2009 8:21 AM

 Ok, thanks for tip about tests in MVC source code.

Now my problem is with View. my result would be:

 

ActionResult result = controller.Index();
result.ExecuteResult(controller.ControllerContext);

  

Of course I've set the fake controllerContext to that controller (used  Scot Hanselman's MvcMockHelpers). But after running I get error that RouteData has no action element. I added:

 

var fakeRouteData = new RouteData();
fakeRouteData.Values.Add("Action", "Index");
fakeRouteData.Values.Add("Controller", "Home");
ControllerContext context = new ControllerContext(new RequestContext(httpContext, fakeRouteData), controller);

  

But after that I get error:

 

System.InvalidOperationException: The view 'Index' or its master could not be found. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
   in System.Web.Mvc.ViewResult.FindView(ControllerContext context)
   in System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)

  

I need to set fake View? I so examples with controller.ViewEngine = fakeViewEngine.. but now I don't think it's possible.

am I right?

Best regards


Thursday, February 19, 2009 10:34 AM

What is the purpose of the test, what were you trying to validate?


Friday, February 20, 2009 4:05 AM

 I what to validate that status code is 200. It seems that whole response object is empty. Before I mocked the httpContext my test failure because I used HttpContext.GetGlobalResourceObject("Strings", text). I mocked httpConext and test run correctly. I thought that with fake response object I could get the status code.

I whated to test that my page from action is renderd correctly. I wanted  to check that status code is 200, that the view name is correct, that on page I have expected html. Right now I only can check that

 

Assert.AreEqual<string>("About Page", result.ViewData["Title"].ToString());

  

Even checking ViewName is strange for me. Because I need to write my app in return View("About") way, even if return View() is correct but it will not set view name. Why should I write return View("some name") even if return View() is correct and should set the name from method name. If the return View() is incorrect it should throw exception.

Best regards