Question

In my HomeController I've got the following:

 public ActionResult Index()
 {
     SetModuleTitle("Welcome");

     return RedirectToAction( "DashBoard", "Home" );       
 }

and SetModuleTitle is defined in a parent class as thus:

public void SetModuleTitle(string title)
{
    ViewData["ModuleTitle"] = string.Format("PM4 - {0}", title);
}

Nothing mind boggling about that. Now I'm trying to write my test to test for the SetModuleTitle method:

 [Subject( typeof( HomeController ) )]
public class when_the_home_page_is_requested_by_logged_in_user_ : context_for_a_home_controller_for_logged_user
{
    static ActionResult result;

    Because of = () => result = HomeController.Index();

    It should_set_the_module_title = () => ( ( ViewResult ) result ).ViewData[ "ModuleTitle" ].ShouldEqual( "PM4 - Dashboard" );      
}

and I rightly get told that

Unable to cast object of type 'System.Web.Mvc.RedirectToRouteResult' to type 'System.Web.Mvc.ViewResult'.

So how would I set up the MSpec test in that case?

David

Was it helpful?

Solution

Ok I think that I've understood where I was going wrong. However, first I must provide the code called by

return RedirectToAction( "DashBoard", "Home" );

public ActionResult DashBoard()
    {
        SetModuleTitle("Dashboard");

        return View();
    }

So, if my understanding is correct, after my test called

Because of = () => result = HomeController.Index();

the RedirectToAction object is returned and the code execution stops there i.e. it does not call the controller method specified within the RedirectToAction. That would make sense because after all what we're doing here is UNIT testing and NOT integration testing. So, it doesn't make sense to test the SetModuleTitle method here.

Instead, code to test the call to method Dashboard should be implemented:

[Subject(typeof(HomeController))]
public class when_the_dashboard_page_is_requested_by_logged_in_user : context_for_a_home_controller_for_logged_user
{
    static ActionResult result;

    Because of = () => result = HomeController.DashBoard();

    It should_set_the_module_title = () =>
        {
            ( ( ViewResult ) result ).ViewData[ "ModuleTitle" ].ShouldEqual( "PM4 - Dashboard" );
        };

    It should_return_the_dashboard_page = () => 
        result.ShouldBeAView().And().ShouldUseDefaultView();
}

If someone more knowledgeable could deny, confirm or otherwise my understanding, that would be great.

OTHER TIPS

In your controller action you do return RedirectToAction which returns a RedirectToRouteResult object, not a ViewResult, that's what it's complaining about.

in order to cast your result object (in de spec) to ViewResult the return statement of your action would have to look like:

 public ActionResult Index()
 {
     //Some code here

     return View(/*here maybe a model object*/);       
 }

In order to fix your test you just need to change this line:

It should_set_the_module_title = () => ((ViewResult)result ).ViewData[ "ModuleTitle" ].ShouldEqual("PM4 - Dashboard");

for this one:

It should_set_the_module_title = () => ((RedirectToRouteResult)result).ViewData[ "ModuleTitle" ].ShouldEqual("PM4 - Dashboard");

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top