CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Kyle Baley - The Coding Hillbilly

"We are stuck with technology when what we really want is just stuff that works" -- Douglas Adams

TestControllerBuilder in MvcContrib

Yesterday, I cracked open the MvcContrib source code to see if it had....ummm...ok, I swear I was looking for something legitimate in there. But as soon as I updated the latest and opened the project, my eyes zeroed in on the TestControllerHelper class. So with a quick mutter of "oooh, shiny" to myself, I proceeded to what I knew would be the dearth of my productivity for the rest of my day.

Sitting here this morning, I can report to you that I am now one step closer to being able to adequately (but still not quite usefully) test controller actions that include a RedirectToAction method. Here's a sample test:

[ Test ]
public void Test_redirect( )
{
  TestControllerBuilder builder = new TestControllerBuilder( );
  var controller = builder.CreateController<LocationController>( );
  controller.TestRedirect( );
  Assert.That( builder.RedirectToActionData.ControllerName, Is.EqualTo( "Job" ) );
}

The CreateController method on my TestControllerBuilder uses Castle's DynamicProxy to create the controller. It also creates a ControllerContext using dynamic mocks from Rhino Mocks similar to the way Haackselman have already showed you and wires it up to the controller.

An interceptor is also attached to the controller to intercept calls to RenderView and RedirectToAction. (Actually, it intercepts all calls but only these two have special handling.) Calls to either method will populate an appropriate object on the builder class. In the example above, I'm using the RedirectToActionData object.

So far, this is all sweet and dandy like raccoon candy. I have indeed verified that it works as advertised. But at present, it seems to work only for controllers that have a parameterless constructor. Which is going to work for exactly none of my controllers.

I have a version working that allows you to pass in constructor arguments to CreateController and will submit it as a patch for MvcContrib, assuming it hasn't already been addressed.

Oh yeah, I remember! I wanted to see if MvcContrib had the Flash feature I saw added to (but not yet used in) CodeCampServer.

Kyle the Forget-Me-Not


Published Mar 19 2008, 10:00 AM by Kyle Baley
Filed under:

Comments

hammett said:

What? You have to rely on dynamic proxies to test your controllers?

# March 19, 2008 11:24 AM

Kyle Baley said:

@hammett: Man, you don't know the half of it...

# March 19, 2008 11:33 AM

Bryan Reynolds said:

What is a dynamic proxie?

# March 19, 2008 12:54 PM

Kyle Baley said:

@Bryan: Like much of my knowledge, it's a term I've never quite learned the definition of but that I know how to use in a sentence to fake it.

I kid (a bit). You can read about the Proxy pattern here: en.wikipedia.org/.../Proxy_pattern. At the risk of inviting a bunch of "that's not quite right" responses, a dynamic version is one that's created on the fly at runtime. So a JobController object created as a dynamic proxy isn't quite a JobController but it looks close enough like one that we can get our job done.

It's the "close enough" part that makes this whole post kind of dicey.

# March 19, 2008 1:22 PM

Ben Scheirman said:

@hammet:  yeah, and _IT SUCKS_.  We've been promised that this will get better.  I know it's a top priority for preview 3.

@Bryan to add to what Kyle said, think of it as runtime code generation of an object.  If you're familiar with the inherit-and-override method of testing currently rampant in most examples (including code camp server) you'll know exactly what the generated code looks like.

@Kyle:  Flash?  TempData is what we're using in Code Camp Server.  Where did you see Flash?

# March 19, 2008 4:06 PM

Kyle Baley said:

@Ben: I saw a couple of extension methods on ViewPage and ViewMasterPage called DisplayFlashMessage or something to that effect. They do indeed use TempData to store the messages but as far as I can tell, they aren't actually used in the project. I went over to MvcContrib to see if there was a formal implementation of the same functionality.

# March 19, 2008 9:31 PM

Dew Drop - March 20, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop - March 20, 2008 | Alvin Ashcraft's Morning Dew

# March 20, 2008 9:21 AM

Will Shaver said:

Gosh, I feel sheepish for not covering argument methods when I wrote that class. If you get a patch into the group I'm sure it'd be appreciated. I've been focused on NHibernate stuff lately and haven't been playing with MVC as much. (But I will soon when the object model is further along.)

# March 20, 2008 11:16 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!