This is a slightly esoteric questions about how public to make constructors when using an IoC container. I'm using java, Guice and Junit4, but I'm sure this question is more general.
Under Best Practices in the Guice docs, it says "Keep constructors as hidden as possible". This is something I quite agree with, so I was happy to go ahead a make my constructors private and rely on Guice for instantiation.
However, this brings up an issue with mocking classes and unit testing. If all my constructors are private, then how can I instantiate something in a unit test and pass in a mocked dependency? Having to create a new Guice module for every unit test seems like overkill to me. Surely, I must therefore actually make those constructors public.
Which brings me to the question: Given that DI is so useful when combined with unit testing, is the best practices in the Guice docs about keeping constructors hidden actually a mistake?.
Read further in the same document, which suggests giving the constructors default access. Then put your unit tests in the same package.
Default access is provided if none of public
, protected
or private
are specified.
From the document you referenced:
As a correction, simply limit the visibility of both your implementation classes, and their constructors. Typically package private is preferred for both, as this facilitates:
- binding the class within a Module in the same package
- unit testing the class through means of direct instantiation