Ok a bit sweeping but I think there is truth in this, if you have to resort to a mocking framework (such as Typemock the one I use) I think it is vital to ask ‘why am I using this tool?’ I think there are three possible answers:
- I have to mock some back box that is huge and messy that if I don’t mock it will mean any isolated testing is impossible e.g. SharePoint
- I have to mock a complex object, I could write it all by hand, but it is quicker to use an auto-mocking framework. Why do loads of typing when a tool can generate it for me? (the same argument as to why using Refactoring tools are good, they are faster than me typing and make less mistakes)
- My own code is badly designed and the only way to test it is to use a mocking framework to swap out functional units via ‘magic’ at runtime.
If the bit of code I am testing fails into either of the first two categories it is OK, but if it is in third I know must seriously consider some refactoring. Ok this is not always possible for technical or budgetary reasons, but I should at least consider it. Actually you could consider category 1 as a special case of category 3, a better testable design may be possible, but it is out of your control.
So given this I looked at the new Typemock feature with interest, the ability to fake out DateTime.Now. Something you have not been able to do in the past due to the DataTime classes deep location in the .NET framework. OK it is a really cool feature, but that is certainly not a good enough reason to use it. I have to ask if I need to mock this call out does my code stink?
Historically I would have defined an interface for a date services and used it to pass in a test or production implementation using dependency injection e.g.
public class MyApplication
{
public MyApplication(IDateProvider dateProvider)
{
// so we use
DateTime date1 = dateProvider.GetCurrentDate();
// as opposed to
DateTime date2 = DateTime.Now
}
}
So in the new world with the new Typemock feature I have three options:
- Just call DateTime.Now in my code, because now I know I can use Typemock to intercept the call and return the value I want for test purposes
- Write my own date provider and use dependency injection to swap in different versions (or if I want to be really flexible use a IoC framework like Castle Windsor)
- Write my own date provider class with a static GetDate method, but not use dependency injection, just call the method directory wherever I would have called DateTime.Now and use Typemock to intercept calls to this static method in tests (the old way to get round the limitation that Typemock cannot mock classes from MSCORELIB
I think this bring me back full circle to my first question: does the fact I use the new feature of Typemock to mock out DateTime.Now mean my code stinks? Well after bit of thought I think it does. I would always favour putting in some design patterns to aid testing, so in this case some dependency injection would appear the best option. Like all services it would allow me to centralise all date functions in one place, so a good SOA pattern. With all my date service in one place I can make a sensible choice of how I want to mock it out, manual or via an auto mocking framework.
So in summary, in mocking, like in so many things in life, just because you can do it is no reason why you should do something in a polite society. If you can, it is better to address a code smell with good design as opposed to a clever tool.