If you’ve never done Test Driven Development or aren’t even sure what this "crazy TDD stuff” is all about than this is the series for you. Over the next 30 days this series of posts take you from “I can spell TDD” to being able to consider yourself a “functional” TDD developer. Of course TDD is a very deep topic and truly mastering it will take quite a bit of time, but the rewards are well worth it. Along the way I’ll be showing you how tools like JustCode and JustMock can help you in your practice of TDD.
Previous Posts in this Series: 30 Days of TDD – Day 26 – Reader Question #2
Adam Hall asks
Just a quick question regarding TDD, encapsulation and DateTime.Now()
I’ve often seen suggestions that you should control the behavior of DateTime.Now so that you can reliably test the way classes react to date times. For example in a calendar application you would likely have a notice about events that happen in the future, but if you don’t control the system time you have to either
a) write a lot of unrealistic cases that happen in the far future
b) write cases that make appointments that are offset from today's date (New Appointment(date.Now().AddDays(5)) and run the risk of having the test cases suddenly stop working due to unconsidered bugs
Controlling DateTime is a solution, but it smells of violating encapsulation, you are affecting objects from outside of their boundaries (and indeed system wide)
In your experience what is the best way to deal with Dates in TDD?
Thanks for the question Adam.
This can be kind of tricky. In general when I see issues like this I like to try to abstract away the thing that changes (the current date and time) from the code under test. What this means that instead of the method having an internal call to DateTime.Now(), I prefer to pass that value in as an argument to the method.
I know that that can potentially lead to parameter bloat, but it enables me to control the date that the method under test is using and makes it testable. When you think about it it’s also a good design practice. If the functionality in my method is bound to a static value, like the current date, it limits my reusability. I can only use that code for situations where the current data and time are needed. I couldn’t use it to recreate the same results later or re-call it to validate my results.
By abstracting everything away that is different between calls I’m taking a more functional approach to designing software. This is best shown by the fact that if I have abstracted all the true external variables away, my method should always return the same results when the same data is used. This not only the definition of testable code, it greatly enhances my code reuse as well.
Hope this helps.
Continue the TDD journey: