Is Typemock too powerful? Will it kill design for testability?
A couple of days ago, Typemock held a small "insiders" web meeting, showing off the new features of the next release. The presentation lasted for about 10 minutes, and we were using Webex to show live screen feed and chat was also enabled (similar to IRC)
Other than some nice feedback we got on what we showed, the most interesting part happened after the presentation was done, and we thought we'd give a few minutes for some small chat about various things.
Suddenly, a question was raised in the chat room about Typemock and good design (I'm paraphrasing): "What do you say to people who think that Typemock should be avoided because it's too powerful?"
There were about 4 Typemock employees in the chat , and 7 "insiders", and suddenly the flood of answers and new questions came in, without warning. In the chaos that ensued for about 15 minutes thereafter, one thing became clear to the powers that run Typemock: There is a big problem of FUD(Fear, uncertainty and doubt) about Typemock, that needs to be addressed.
What the FUD?
Many people are calling people who use mocking frameworks to avoid using Typemock because it makes it easy to avoid common design decisions that your tests "flag" as you try to write them. The claim is that Typemock , because of its ability to mock out practically anything, from statics, to LINQ queries to private constructors to sealed classes, makes the job of writing a test lose sight of design decisions about making the code testable in the first place.
That could be translated to "You will not design for testability if you use Typemock". But it can also be interpreted as :
- I don't trust the people who write the tests enough to give them a tool that makes it easy to avoid design decisions.
- People will default to a worst practice just because its easier
- "Real" developers who write "real" tests will never need Typemock if they follow the TDD rules
So, let me try and address some of the concerns relating to design for testability and using Typemock:
1. You can still design for testability and use Typemock
It may sound weird, but just because you're using a tool that allows you to mock out static methods, doesn't mean you should go ahead and sprinkle statics as far as the eye can see. If your car lets you drive 200mph does that mean you'll choose to do that in a crowded street?
Test Driven Development has three main steps, and the first one is about writing a test that fails, even before the code under test is written. you can choose to write that piece of code under test in any design you like, and you can still do it with interfaces, Dependency injection and IoC principles.
For new, greenfield code, you can use TypeMock just like you could use Rhino.Mocks. I know I've said other things in the past, but since I've been "inside" I've been using Typemock more and more and it really doesn't prevent you from doing anything you'd have done before.
2. If you were doing bad design before, the tool won't help you, just the technique.
Using TDD to get good design is still possible with TypeMock, especially if you use the Natural Mocks syntax (Record-replay, much like Rhino.Mocks). Choosing a framework based on it having more constraints is not a good idea. Why? Because you can still write poorly testable code with Rhino.Mocks if you weren't doing it TDD style.
3. Sometimes you just can't refactor your legacy code into testability.
Will you avoid testing it just because using non Typemock frameworks isn't possible? Or will you be pragmatic about it and do the thing that helps you write tests for code that is currently untestable? I would rather have a framework that gives me the choice of having a hammer and not using it, than not having it at all.
4. Pair Programming, Test reviews and Design reviews trump any tool
If you don't trust people to do good design, review the code with them.l use Agile techniques. If I write code with someone else, if I review tests that other people have written, and if I review designs other people came up with, I can tell on the spot what is poorly designed, what is not testable, not extensible etc.. If you're working alone and all you have is your framework to save you, you don't have much anyway. And it won't save you, it will just make it harder for you to write the code you want to write, with the design you want to use
5. If you're not sure how you'd design something and test it, you can always ask!
That's why god invented forums, mailing lists and the like. you can start at our new forum about techniques and best practices with unit testing. I'll be monitoring it personally and would love to start a conversation there or on this blog. whatever you like.