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
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.
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.
精彩评论