Testing MonoRail Controllers from Castle’s Trunk

Note: This post was on my old blog, but it is linked to using.castleproject.org and I wanted to move it to my new blog for future reference.Originally, Hammett placed a AbstractMRTestCase in the same namespace to facilitate testing of controllers. This class simulated a browser by supplying the user with access to session, request, response etc… This class didn’t work too well and was clunky to use. The guys at Eleutian came up with their own solution awhile ago that you can read here. This worked by mocking out everything that the Controller class needed using Rhino Mocks. This worked much better, although it was a little tricky to pull down and use yourself.
Enter BaseControllerTest! This works off of Eleutian’s example and makes the whole deal much easier. Here is an example of how you would go about using it.
First, Your Test Fixture must derive from BaseControllerTest. In this example I am testing a SearchController I made for CMS software:

public class SearchControllerTestCases : BaseControllerTest{}

Next, You must instantiate your Controller class. I do this in the SetUp method, as I am using the Controller in more than one test and I don’t want to violate the DRY principle:

public void SetUp()

_mocks = new MockRepository();

_searchService = _mocks.CreateMock();

_searchController = new SearchController(_searchService);

As you can see I am also passing in a mock of a Serivce that is provided by Windsor at runtime. Now we have created our controller and set everything up. Now we are ready to perform our first test. The following test Searches for a Teacher by their username. Note in the test that I make a call to PrepareController. This sets up the controller with the specified area, controller and action. Take a gander at the code for BaseControllerTest class here and it will give you a much better idea of what PrepareController is doing. All it does is setup the IRailsEngineContext by creating instances of mock classes that will respond to your test. Here is the code in my test to perform SearchForTeacher():

[Test]public void CanSearchForTeacher(){IList teachers = new List();PrepareController(_searchController, "", "Search", "FindTeacher");string teacherName = "username";using (_mocks.Unordered()){Expect.Call(_searchService.FindTeacher(teacherName)).Return(teachers);}_mocks.ReplayAll();_searchController.FindTeacher(teacherName);_mocks.VerifyAll();}

So the only mock expectation I need to setup here is for SearchService.FindTeacher that is called when FindTeacher() is called on the controller. If I had values that needed to be set such as PropertyBag values, or CurrentUser. All you need to do is just set them by using the Context variable available through BaseController test like so:

[SetUp]public void SetUp(){MockRepository _mocks = new MockRepository();_webSiteManageController = new WebSiteManageController();_user = _mocks.CreateMock();PrepareController(_webSiteManageController, "manage", "WebSite", "List");Context.CurrentUser = _user;}

Note where I am setting Context.CurrentUser as it is accessed through this Controller on the AuthorizationFilter I have setup on the WebSiteManageController class. This way, everytime the AuthroizationFilter is run, it will return true to allow access to the underlying controller.Hopefully that gives you a jump start on using Castle’s new Controller Test support! Have fun!


4 Responses to “Testing MonoRail Controllers from Castle’s Trunk”

  1. Jason Meridth Says:

    Excellent post. I will reference this in my next MonoRail post.

  2. schambers Says:

    thank you Jason! Hope it was helpful.

  3. Quick Tip: Asserting response redirects in a MonoRail controller test - joeyDotNet Says:

    […] this post by Sean reminded me of when I first started using the trunk's BaseControllerTest.  One […]

  4. Monorail #3 : Unit Testing and ViewComponents - J.D. Meridth Says:

    […] the past 2 1/2 posts I've migrated my unit tests to use the BaseControllerTest abstract class that originated from the Eleutian guys, but is now a part of the Castle MonoRail trunk […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: