Earlier this week I was talking with a system architect. He mentioned what I consider a sensitive and interesting question. How do you use Dependency Inversion (DI) to test software? If you are interested in this question please stop reading and allow yourself a few minutes thinking about the question and associated answer.
OK you are back. I used the qualifiers sensitive and interesting. Perhaps I could also have added tricky to describe the question. Allow me to go over my thought process.
DI and Inversion of Control (IoC) a similar by slightly different concept were developed over a couple decades ago. They were created with the advent of Object Oriented Design (OOD). Today there are many tools and frameworks that simplify using DI and IoC in software projects.
We all know that in small projects many developers jump into a solution by using a familiar template. Then they add code to address the requirements at hand. In the process some testing is performed but typically most testing is performed after the code is completed. Such approaches contradict Tests Driven Development (TDD) techniques that were introduced around the time of OOD was conceived.
Many books written by the OOD pioneers describe how software should be developed using a TDD approach and the benefits it has to the architecture and design.
TDD dictates to test before the actual implementation code is done. The idea is to come up with a suite of tests and fail them all before implementing the actual classes. If needed, empty classes and dummy (do nothing) methods will be put in place so the code compiles yet fails to execute. I always develop code using the TDD approach. It is amazing how changes to the initial architecture, design and implementation contribute to a simpler and more robust code. Note that I am not using the qualifier shorter. Shorter code (code with less LOCs) is not necessarily better or more elegant. In most cases it is harder to understand and maintain.
Now let’s go back to the initial questions. If the software is being architected and an initial design is put in place, a TDD approach would require testing be implemented before filling in the specific classes for the project. As was stated before, testing with a framework or for example in Java using JUnit would be a task started after the base architecture and design is under way. If the architect is not part of the testing then the value of TDD seems to go out the window.
Of course once the basic architecture and design are in place, other members in the team may code the actual tests keeping the architect and the rest of the team up to speed with their results and suggestions. That is where a team using Agile will shine.
In OOD there is a Dependency Injection Principle (DIP) which is well described in numerous articles and books. Among others I own copies of “Dependency Injection in .NET” by Mark Seemann and perhaps even closer to the subject “Agile Software Development Principles, Patterns, and Practices” by Robert C. Martin. While I read a book I tend to use a marker and a pen to underline and comment on what I find interesting. The book by Martin is filled with annotations.
I will follow up on this post with some simple code to illustrate how I would include tests to an initial architecture / design. I will probably use the DIP in the architecture / design and then jump into JUnit. Always keep in mind the TDD approach.
So what do you think about the original questions? Hopefully you share my comments regarding sensitive and tricky (if you are a system architect) and interesting.
I would like to hear your comments / opinions on this subject. Please feel free to send me a message. I will respond and will not use your name unless you explicitly allow me to do so.
Follow me on Twitter: @john_canessa