Today I attended a talk about mocking in order to facilitate unit testing. The example used was a “UsersService” that accepted a repository as a constructor argument. Essentially it was doing CRUD and forwarding the calls almost straight on to the repository:
The interesting part was when we got to testing “Create“. The problem is that it’s non-deterministic so we wouldn’t be able to consistently test the result. The speaker asked “How do we verify that a new Guid was created for the added user?” and someone in the audience half-joking responded “By passing in a Guid service…”
The speaker went on to implement a “GuidProvider” type that was effectively a singleton, which needed to be set-up/torn down for each test and would have to be set once in the production code. He said that as Guid is a standard .NET type (like DateTime), that it can be relied upon to always be there and is therefore an acceptable dependency. I think this is a misreading of Mark Seemann’s book Dependency Injection in .NET, where he is talking about assembly dependencies as opposed to class dependencies.
I find all this very curious!
I believe calling a function that returns a new Guid a “Guid Service” and laughing at it is a form of Reductio ad absurdum. It does sound absurd, but only because the verbosity of the language and OOP style make it so. If it is instead thought of simply as a function that takes no arguments and returns a Guid then suddenly it doesn’t seem so absurd:
To initialise an instance of this class, one would just provide it with Guid.NewGuid. To use an object instead of Func<> one would have to write the boilerplate of an interface and class declaration, which when couched with the damning term “Service” inevitably makes it seem more grand and frivolous than it really is.
When the speaker mentioned DateTime in the same breath as the Guid problem it reminded me of my earlier post about my disdain for Microsoft’s Shims. It feels like these types are given undue respect by my fellow developers – as if they’re intrinsically untouchable somehow in a way that the rest of our code isn’t.
I think we should consider our dependencies carefully, especially when their use is so ubiquitous that they’re ingrained in the nooks and crannies of our code. Acceptable dependency may just be another name for hidden dependency.