Search code examples
asp.net-mvc-2testingmspec

Set up test using MSpec with MSpecMVC, RedirectToAction and ViewData test condition problem


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


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.