BDD with MSpec and Rhino Auto Mocks (part 1)
November 10, 2009 · 3 minute read · Tags: Agile | BDD | MSpecs | RhinoMocks
I’ve long been a fan of test driven development in theory but in practice have experienced many of the issues which turn people off TDD and unit testing in general.
Brittle tests which do too much, tell you very little about the meaning behind the code and are more a hindrance than a help when it comes to making changes at a later date.
Well as you may have guessed, given the title of this post, I have found an answer to these problems in the form of BDD using MSpec and Rhino Automocking. I have been using this approach for a good while now and continue to be pleasantly surprised by just how much fun it is writing my tests, but also how stupidly easy they are to change, and how well they document my project’s requirements.
Update: You can get MSpec from github****.
External Tool
It’s a good idea to set up an external tool in Visual Studio to run your MSpec tests and produce html output.
Create a new external tool which launches mspec.exe with the following arguments.
$(TargetName)$(TargetExt) --html "$(ProjectDir)Report.html"
Make sure the initial directory is $(BinDir) and tick Use output window.
Using your favourite Test Runner
Included in the MSpec download are scripts to configure various test runners to recognise and run MSpec tests.
Simply run the bat file which relates to your build runner and way you go!
Writing Specifications
Ensure you add a reference (in your Tests Project) to Machine.Specifications.dll.
Now the fun begins.
I’ve created an ASP.NET MVC site and empty class library Tests project.
Let’s say we want to create a simple page which allows users to search for a product.
We’ll start by creating a new folder in our tests folder called Controllers and add a new class file called ProductControllerTets.cs
Having discussed this feature in detail with the client, I’ve a pretty good idea of what they want, so I start with the following.
- using Machine.Specifications;
- namespace MSpecExample.Tests.Controllers
- {
- [Subject("Product Search")]
- public class when_product_search_page_requested
- {
- It should_return_product_search_page;
- }
- [Subject("Product Search")]
- public class when_asked_for_products_matching_search_term
- {
- It should_retrieve_a_list_of_products_with_titles_containing_the_search_term;
- It should_return_the_list_of_products_to_the_user;
- }
- [Subject("Product Search")]
- public class when_empty_search_term_entered
- {
- It should_return_an_error_message;
- }
- }
What I particularly like about this, is that you can really think about exactly what you’re doing and express it in code which will eventually become executable tests without actually implementing any code (yet!).
If we now build our test project and run the tests using the console runner via the external tool we set up earlier), we’ll get a report.html file in the tests project which looks like this…
In part 2, we’ll start implementing these tests.
In part 3, we’ll introduce Rhino AutoMocker.