What a pain!
If a controller’s action method returns RedirectToView(“NewView”) the result is a RedirectToRouteResult. This is good.
Unless the routing engine is actually in play (which it isn’t while we’re unit testing) the actual NewView action method won’t be called. Which is kind of good because it forces you to test one action method at a time. But what if your action method returns multiple RedirectToRouteResults?
public ActionResult Index()
{
var viewModel = GetViewModel();
if (SomethingNotRight(viewModel))
{
// redirect to error page
return RedirectToAction("Error");
}
else if (SomethingDifferent(viewModel))
{
// redirect to details page
return RedirectToAction("Details");
}
return View("Index", viewModel);
}
At first glance our test would look something like this:
[TestMethod]
public void Index_WithZeroItems_ReturnsErrorView()
{
// Arrange
ItemIndexViewModel mockViewModel = MockRepository.GenerateMock();
mockViewModel.Expect(m => m.GetItems()).Return(new List()).Repeat.Any(); // should redirect to Error
var controller = new ItemsController();
controller.ItemIndexViewModel = mockViewModel;
// Act
var result = controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
}
So we have asserted that A RedirectToRouteResult has been returned, but which one?
The RedirectToRouteResult exposes a RouteName property and RouteValues property.
What it DOES give us though, is the RouteValues property is a dictionary populated with the name of the action we redirected to. So to check which action we’re redirecting to we simply have to check the name of the action within the dictionary. So our test method becomes:
public void Index_WithZeroItems_ReturnsErrorView()
{
// Arrange
ItemIndexViewModel mockViewModel = MockRepository.GenerateMock();
mockViewModel.Expect(m => m.GetItems()).Return(new List()).Repeat.Any(); // should redirect to Error
var controller = new ItemsController();
controller.ItemIndexViewModel = mockViewModel;
// Act
var result = controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
Assert.AreEqual("Error", (result as RedirectToRouteResult).RouteValues["action"]);
}
So we tested that the CORRECT RedirectToRouteResult is returned, just as expected.
No comments have been posted yet