Search code examples
asp.net-mvcunit-testingrhino-mocksmvccontrib-testhelper

Error using MVCContrib TestHelper


While trying to implement the second answer to a previous question, I am receiving an error.

I have implemented the methods just as the post shows, and the first three work properly. The fourth one (HomeController_Delete_Action_Handler_Should_Redirect_If_Model_Successfully_Delete) gives this error: Could not find a parameter named 'controller' in the result's Values collection.

If I change the code to:

actual 
    .AssertActionRedirect() 
    .ToAction("Index");

it works properly, but I don't like the "magic string" in there and prefer to use the lambda method that the other poster used.

My controller method looks like this:

    [HttpPost]
    public ActionResult Delete(State model)
    {
        try
        {
            if( model == null )
            {
                return View( model );
            }

            _stateService.Delete( model );

            return RedirectToAction("Index");
        }
        catch
        {
            return View( model );
        }
    }

What am I doing wrong?


Solution

  • MVCContrib.TestHelper expects you to specify the controller name when redirecting in the Delete action:

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

    Then you would be able to use the strongly typed assertion:

    actual
        .AssertActionRedirect()
        .ToAction<HomeController>(c => c.Index());
    

    Another alternative is to write your own ToActionCustom extension method:

    public static class TestHelperExtensions
    {
        public static RedirectToRouteResult ToActionCustom<TController>(
            this RedirectToRouteResult result, 
            Expression<Action<TController>> action
        ) where TController : IController
        {
            var body = (MethodCallExpression)action.Body;
            var name = body.Method.Name;
            return result.ToAction(name);
        }
    }
    

    which would allow you to leave the redirect as is:

    return RedirectToAction("Index");
    

    and test the result like this:

    actual
        .AssertActionRedirect()
        .ToActionCustom<HomeController>(c => c.Index());