views:

294

answers:

2

I have the following HandleUnknownAction set on my base controller class:

protected override void HandleUnknownAction(string action)
{
    Response.Redirect("/");
}

How can I unit test that? Another point, is that way to handle the unknown action correct? Seems that calling RedirectToAction() would be more correct but the HandleUnknownAction doesn't have a return value.

The far I could get to test that is:

[Test]
public void TestHandleUnknownAction()
{
    ctroler.ActionInvoker.InvokeAction(ctroler.ControllerContext, "unknown");
}

I'm stuck at it.

+2  A: 

I don't think there's a need to test that HandleUnknownAction is invoked when a controller is missing an action. We trust the framework to handle that. So we can test the implementation by calling HandleUnknownAction directly with the mocking framework Moq. Should also be possible with Rhino Mocks.

public void TestHandleUnknownAction()
{
    Mock<ControllerContext> cc = new Mock<ControllerContext>
                                           (MockBehavior.Strict);
    cc.Expect(c => c.HttpContext.Response.Redirect("/"));

    TestHelperController controller = new TestHelperController();
    controller.ControllerContext = cc.Object;

    controller.InvokeUnknownAction("test");
}

Where TestHelperController makes the HandleUnknownAction accessible:

public class TestHelperController : RealController
{
    public void InvokeUnknownAction(string action)
    {
        this.HandleUnknownAction(action);
    }
}
Dala
Got your point about calling HandleUknownAction, but what is that Mock object magic behind? Where this object come from? That Expect function is what I'm looking for.
Augusto Radtke
Forgot to mention Moq, sorry. Updated the answer with a link.
Dala
Man, that Moq library is a dream, you got it, all the reputation belongs to you!
Augusto Radtke
A: 

That's fine for a simple Response.Redirect but that unit test code will not work if you want to do something more complicated like rendering an error view:

// TODO - Put some stuff into ViewData or a model
View("Error").ExecuteResult(Me.ControllerContext)