Designing for testability overcomes the need for testing

In my previous post, “How to mock static class or static member for testing”, Eli replied that mocking static data can be easily achieved via TypeMock with no extra work around it. Although Eli raised a valid point while TypeMock is a very strong framework that you should check out, I still believe that designing for testability overcomes the basic need for testing your code. Trying to use some sort of powerful Profiler-based framework in order to mock your “wires” is a great thing, but I would use it only if refactoring the code will take too much time or effort that will beat the value of performing the change.

I would like to make my teammates think toward testability while designing the API.

Breaking your code so it will be easily tested will make things a little bit more complex in terms of dependency injection (object A will need to get IB in its constructor in order to work rather then creating new instance of B inside of it), but the allegedly weakness of breaking your code, making you stray from the pure OOP you’ve learned in “OOP for dummies” courses at the university, is the exact strength I see in TDD. Designing the code by writing use-cases, playing with the API, breaking classes for Single Responsibility and constant refactoring wins the purpose of testing solely or pure OO code. Don’t get me wrong, pure OO is nice on the surface, but don’t get fooled by it. You write code to create successful software, not successful practice of old paradigms.

TDD constantly demands to re-design the system and refactor it to fit the needs the system invocate, having the tests will back you up in the path. This way you can follow the guidelines of a sane development process:
1). Design the general architecture (the big picture)
2). Agree on interfaces between components
3). Unit-test user stories (use-cases) and drill down into the design by each test.
4). Build Integration tests to connect between components.

and so on…

Now, if you want to refactor existing code or add new behaviors, it’s simple:
1). Refactor the code.
2). See that everything compiles.
3). Run unit & integrations tests.
4). If all is good – check-in your source.

Claiming that TDD-OO is not pure OO is fine by me. I would prefer TDD-OO based code on pure OO any day.


Oren Ellenbogen