Inversion of Control is NOT about testability
Jacob have an interesting perspective on testability:
The thing is that using Typemock means that you can unit test literally any public method of any public class, regardless of any and all internal dependencies that class might have. And you can do so without changing the design and/or architecture of your software at all.
In other words, using Typemock means that everything is testable. Unit testable. Seriously. Everything.
....
Which is why I had such a hard time reading Jeffrey Palermo's latest blog post entitled “Inversion of Control is NOT about testability”. Since I know Jeffrey Palermo is a .Net developer, my initial response is a big fat “Duh. He must be using Typemock.” Sadly, this is not the case.
...“Testable design” only has value in the things it allows us to do—namely, unit test our classes. If we can unit test our classes as easily no matter what design patterns we choose, then that frees us up to explore other aspects of design choices. It isn't that <le design du jour> ceases to have value, it's just that testability is no longer a factor in evaluating its utility.
...So, uh, forget all I just said. Spend lots of time making sure your .Net projects are testable. Also: Typemock sucks. Don't bother going there...
There are so many things that I disagree with in this post, I am not sure where to even begin. Before that, I need to point out, as usual, that TypeMock is an awesome tool, and that it can bring a lot of value to the table. It doesn't fit the way that I , personally, works, but that is a personal opinion, and I am just a little bit biased. I just want to make it clear that this post is not an attempt to dismiss TypeMock or its value.
With that out of the way, let us concentrate on the actual content of the post.
First, there is no silver bullet. TypeMock is wonderful, but it is not the answer to every testability prayer (is there such a thing?). If the code is bad, TypeMock can do a lot to help, but it will still be a PITA to test this code.
Second, it looks like Jacob missing the actual message in Palermo's post about "this is not about testability". Good design is one which preserves separation of concerns, maintain the single responsibility principal, amenable to change, etc. This also happen to be a design that is easily testable, but that is beside the point.
Good design is simple one where each piece of the code does one thing, and is not dependent on everything else in the application. To violate that means that you would run into issues the first time you need to make a modification. The reason that we want to avoid dependencies as much as possible is that we have to avoid the cascading change reaction.
I didn't have to look far for an example, two posts prior to this one, Jacob has given an excellent example why a design that is testable with TypeMock (and thus, holy*), run into problems with real world requirements. This is not my scenario, it is his. I can come up with quite a lot of war stories about the problems that code with too much dependencies caused.
Let us take Rhino Mocks as an example (I still think of it as my best work), the project is over 3 years old, started in .Net 1.1 and C# 1.0. It has got through numerous versions and grown through two (and a half :-)) major framework versions. The code is stable and as usable as the the day I started this project. If you dig into Rhino Mocks, you'll find that the code is heavily segregated. That allowed me to add functionality and modify the way things work without difficulty, even when dealing with major changes, like the move to Dynamic Proxy 2 or support the AAA syntax.
That is what you get out of having a good design, software that is maintainable.
* sorry, this is a snipe at Jacob, not TypeMock.
Comments
What are they talking about anyway? Testing is one thing, design is another.
If you're going to snipe, at least ****try to understand my point. At the very least, it should be clear from my post that I did ****not miss Polermo's point about Inversion of Control. The fact that testability is beside the point is my problem with how testability nevertheless entwines itself in these discussions. If testability is truly beside the point, then stop injecting it into ****every discussion of IoC/DIP/SoC! Polermo's discussion of coupling would have been ****far more interesting if he would have stuck to the premise of his title. Instead, his asides about testability as a beneficial side-effect distracted from his point and prevented delving further into the things that supported his argument ****better .
And I'm not all that fond of your characterization of my motivations, either. Typemock is holy? Please. I beg you to point out anything I've ****ever said that would imply that Typemock is anything more than a useful tool. Freeing us from needing to turn elsewhere for testability is hardly a call for sainthood.
Finally, if you're going to use my own posts against me, try to at least represent them accurately (even if you don't want to give me credit for honest and open exploration of a tricky topic). Testing and testability had absolutely nothing to do with the trade-offs explored there and since I didn't use Typemock in the testing of that product (the provider pattern is as easy to test as DI for most test frameworks), that article hardly invalidates anything I've said... ever.
I think this is more about what Jeff Palermo meant with good design:
http://ferventcoder.com/archive/2008/08/23/test-driven-success-story-plus-side-effects-of-good-design.aspx
Good design makes your code maintainable. Testability is only ONE of the benefits.
Comment preview