views:

246

answers:

3

I'm trying to write a test for an ASP.NET MVC controller method. I've got RhinoMocks (since it seems to be the most popular and best supported), and MvcMockHelpers (since it seems like I need that).

My test method looks like:

var controller = new MyController();
MvcMockHelpers.SetFakeControllerContext(mocks, controller);
mocks.ReplayAll();
var result = controller.MyAction(arg1, arg2);
// then i'd make assertions on the result

This doesn't work, because the RouteData has no entries, and MyAction depends on having a bunch of values set there, like "controller" and "action".

I know I can build a custom RouteData for each controller method I want to call, but that seems silly. What part of ASP.NET MVC is responsible for setting this, and how can I get in that code path?

(I feel completely lost here, so if I'm barking up the wrong tree, let me know that, too.)

A: 

I suggest that you split your unit testing into routing tests and controller tests. The routing tests will test the routes independently of the controllers. This frees you to test your controllers conventionally, like any other Plain Old CSharp Method.

Phil Haack and Adam Tybor have good articles on how to test your routes:

Testing Routes In ASP.NET MVC
http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx

Testing Routes using Rhino Mocks
http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/

Robert Harvey
I have no great desire to test routing -- I just wanted to set up RouteData so my controller would run. But controllers depend on a bunch of state that ASP.NET MVC sets up for me (like RouteData, but also a bunch of other things, apparently). Is the accepted way to simply write mocks for *everything* the controller touches? That sounds fine, but maybe a lot of work (especially when the app wasn't written with that in mind). Is it very hard to get ASP.NET MVC to run its normal response routine, and just hand me the result?
Ken
The MVCContrib helper that Sam suggests seems like it would do what you want.
Robert Harvey
A: 

The CodeCampServer way of building and testing routes may be of interest to you.

RouteConfigurator: (note it clears the routes every time RegisterRoutes() is called--required for the MVCContrib route testing helper) http://code.google.com/p/codecampserver/source/browse/trunk/src/UI/RouteConfigurator.cs

IncomingRouteTester: uses the MVCContrib route testing extensions to efficiently test routes: http://code.google.com/p/codecampserver/source/browse/trunk/src/UnitTests/UI/Routes/IncomingRouteTester.cs

Browsing the source of this project (among others) has answered a lot of questions for me, and I'd recommend you download the source and take a look around the unit tests project, if nothing else.

Peter Seale
+1  A: 

I've found the best luck with MvcContrib Test Helper, which uses RhinoMocks.

This is a decent intro

And the MVC Contrib project is on CodePlex

sgwill