I wrote blog post about testing field injection with Mockito (using
@InjectMocks/@Mock/@Spy). It describes how to inject dependencies into testing object. But I didn’t pay attention to thinking about problems of field injection itself. Let me summarize few arguments against field injections that convinced me to treat it as bad practice:
- Field injection hides class dependencies. Constructor injection on the other hand exposes them. So it’s enough to look at class API.
- Constructor injection doesn’t allow creation of circular dependencies.
- Constructor injection uses standard Java features to inject dependencies. It is definitely much cleaner than field injection which involves using reflection twice under the hood:
- Spring must use reflection to inject private field
- Mockito (during the test) must use reflection to inject mocks into testing object
- Developer would need to create awful non-default constructor with a lot of parameters for tightly coupled class. Nobody likes huge amount of parameters. So constructor injection naturally forces him to think about decoupling and reducing dependencies for the class. This is biggest advantage of constructor injection for me.
So I am another member of Constructor injection camp now. This nice Petri Kainulainen’s blog post gathers more reading about pros and cons of both approaches.