Tales of ‘Mock’ing birds and OO design
In my previous post, i talked a bit about using the Model View Presenter in the ASP.NET project im doing and the videos of Jean Paul Boodhoo and others that gave me the necessary material to do the work.
The thing that most impressed me with JPB’s videos was the use of Mock Objects. I have been aware of them for a long time but never had any reason to use them, being primarily in the Biztalk world. I have recently read about using IoC/DI & mocks in pipeline components and custom adapters but have never had the chance. I was pleasantly surprised to find that i had quite underestimated what can be done with mocks. I always saw them as ‘fake’ data suppliers and didnt realise how you nicely can test the behavior of the system with them. I’ve adopted them wholesale now and have quite fallen in love with the approach of mocks and depedency injection. If only we could unit test Biztalk like this!!
I decided to keep things simple and have used only NMock2. The best article i found is in MSDN Magazine – Exploring the Continuum of test doubles. This is a really good resource explaining the range of different types of test helpers- dummy data, fakes, stubs, mocks and so on. I had a brief look at Rhino Mocks and it seems very powerful but reading through the material on the new kid in town , MoQ, i think i will go with MoQ in future as i dont quite get the point of the Record and Replay syntax of Rhino and others. TypeMock seems quite brilliant too with its ability to mock concrete classes as well which, IMO, is a boost in brownfield systems that dont have (m)any interfaces or opportunities to inject things into the system under test. I dont think MsTEST has any mocking capabilities yet, but maybe there is ..
But the time i spent researching mocks brought to light just how much (mostly) pointless academic debate there is about these things. There are heated debates on blogs about whose approach is ‘purer’, classic TDD vs. mockist TDD and all sorts of things. To some extent, these discussions are educative, but then they soon descend into weird stand-offs which does no one any good. This is why i have taken a liking to the approach in MoQ – mainly because Daniel Cazzulino (kzu) and the other Clarius chaps who started it seem very pragmatic rather than being stick in the mud purists. Check out some of Daniels posts here , here and here ) These tools are all good, Rhino, NMock2, MoQ, TypeMock and we should be highlighting their strengths and applicability to different situations and getting more people using them rather than arguing over whose approach is the right one. Lets face it, NO ONE is going to agree on what ‘correct’ OO design is (if there is such a thing). Interfaces are great, but they can be overused. Classic TDD state based tests are great but only for state testing.. Mocks are great but just for behavior. There are those who think that even using mocks is a ‘smell’ Heck, to some folk, using X is a ‘smell’ and to others not using it is a ‘smell’. Frankly, these debates stink. 🙂
If i hadnt started seeing a glimmer of light with my simple forays into NMock i would have avoided mocks altogether, actually, i would even avoid TDD altogether if i were to pay much attention to these silly arguments and posturing. If you can write all your tests first, good. I’m happy for you. Just because i write some tests before and some tests after, doesnt mean i care less about my code. And yes, according to me its perfectly fine to buy/use a tool that will generate unit tests for my code because, at the end of the day, i want the code to be tested (actually i dont use any test generators… yet…) . I agree theres less code to write when you write the test first (or at least stub out your expectations) and you’re more likely to write better quality code in small increments but when you inherit a project do you care what came first, as long as there is a good set of tests?
Anyway, enough of my rant..but hey, i do feel better for having got that off my chest!!. So, back to the point, i used IoC quite a bit, injecting views into presenters, service agents into presenters, services into service agents etc and ended up covering the codebase with a wide variety of tests even before i wrote a single aspx page. I enjoyed the opportunity to think through the behavior of the system in a white box manner rather than just relying on state based tests. I do have quite a few state based tests now but only wrote them when i had exhausted all tests on behavior and had to check the exact return values.
Having done all this, i was overjoyed to go back to the old orchestration designer when i had to add a couple more features to one of those backend services. It seemed like a trusty old friend not like those weird GridViews and their datasource pals!!! … Mocks are cool, maybe we will see more of them in the biztalk world, but for me personally, i cant wait to finish off the ASP.NET and go back Biztalk and WebServices.