Why field injection causes class is difficult to test?
dependency-injection, guice, java, mockito, unit-testing
Solution
Field injection is more difficult because there's necessarily reflection involved; for example, if you were testing a class with constructor injection, you'd just create mock dependencies and pass them to `new`. Writing directly to private fields requires a good bit of bookkeeping.
Note, however, that that talk is more than four years old. As you demonstrate, tools for dependency injection (both for testing and production) have come a long way since then, and `@Inject` is the official Java standard now. You can use a test framework to handle all of the reflection for you and easily test objects with injected dependencies.
Problem
According Google I/O 2009 - Big Modular Java with Guice (at 29:55) using field injection makes testing harder than constructor or setter injection. Let's consider NewsService class: ``` public class NewsService{ @Inject Storage storage; @Inject Authenticator auth; public void addNews(String data){ if(auth.authenticate()){ storage.save(data); } } } ``` and unit test for NewsService: ``` @RunWith(MockitoJunitRunner.class) public class NewsServiceTest{ @Mock Storage storage; @Mock Authenticator auth; @InjectMocks NewsService sut; //system under test @Test public void addNews_ShouldCallSaveOnStorage_WhenAuthIsSucceed(){ when(auth.authenticate()).thenReturn(true); sut.addNews("mocked data"); verify(storage).save("mocked data"); } } ``` Mockito can inject mocks even to private fields. Taking care about encapsulation is important, so I use package visibility. Even if Storage and Authenticator classes are in different package than NewsService and both still use package visibility for their own fields, I don't care about it, because NewsService don't have to access any field from Storage or Authenticator, because I mocked their behaoviour. Even if I would change NewsService to use constructor injection, my unit test class wouldn't change. So the question is: does field injection really causes testing harder with keeping well-designed architecture?