(Scott left a comment that made me edit this post a bit)
In less time than it took me to write this post. Can you believe that?? He learned to drive design. He got it!
We started our lesson when I was writing another post about TDD (big surprise, right?). He said I should post some examples. I said that my examples wouldn't be useful without the reactions of the audience. Everyone learns differently.
He gave me a simple example to do, test drive a class that writes "Hello World" to the console. I started explaining what makes this simple problem not so easy to test and we decided to try out the example together.
Asking questions is a great tool to help someone learn, it makes the learner realize conclusions. Figuring out the right questions is always difficult and this morning was no different.
I asked lots of questions. They were focused on one thing: How can I make the introduction of a mock organic?
Eventually he suggested we put Console.Writeline in our CUT, then we refactor it to be testable.
This made me realize my questions were not right.
I needed to teach him how to think in the test. I knew this was a major key how I learned TDD, but I thought it was an evolution.
I was wrong.
In this moment, I realized that learning TDD isn't about writing tests. Its about leveraging polymorphism to verify responsibilities and interactions.
Once I realized this, I only needed to ask one question:
Is there a way we can put something between our CUT and the System.Console to verify the right method was called?
In a few minutes we had an IConsole and a MockConsole implementation. A few minutes later we had a working test, a minute after that we had a console application that wrote hello world.
During his implementation of MockConsole, he found many limitations. After we had a working application, we went back in the test and replaced MockConsole with a RhinoMock.
In the end, he understood how the test drove his design, why it did, why he used a mock and appreciated a mocking framework.
It was awesome.
I'll let his reflection on his learning speak for itself:
I really like TDD. The code you end up with is really good. Its the minimum amount of code to write to make your code testable. The difficulty between just programming and test drivent development is very different...
On the first day of college, you write hello world straight to the console without any understanding of coding, its the real basics.
On your first day of TDD it takes a few layers in between to do it right, its geometrically more complicated, but its only adding a some subtle difference, like IConsole. It gives you the round trip of object oriented programming with simple examples that really illustrate why you do the things you do with object oriented programming. It really takes a great understanding of OOD to appreciate TDD and do it right.
Deciding what tests to write and how you write them are hard, harder than writing the code.
Thank you, that was nice.