为什么现场注入导致类很难测试?

时间:2013-12-05 08:38:57

标签: java unit-testing dependency-injection guice mockito

根据Google I/O 2009 - Big Modular Java with Guice (at 29:55)使用字段注入使得测试比构造函数或setter注入更难。

让我们考虑一下NewsService类:

public class NewsService{

    @Inject Storage storage;
    @Inject Authenticator auth;

    public void addNews(String data){
       if(auth.authenticate()){
          storage.save(data);
       }
    }
}

和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甚至可以向私人田地注入嘲笑。注意封装很重要,因此我使用封装可见性。 即使Storage和Authenticator类与NewsService位于不同的包中,并且两者仍然使用自己字段的包可见性,我也不关心它,因为NewsService不必访问Storage或Authenticator中的任何字段,因为我嘲笑他们behaoviour。

即使我改变NewsService使用构造函数注入,我的单元测试类也不会改变。

所以问题是:现场注入真的会导致测试更难以保持精心设计的架构吗?

1 个答案:

答案 0 :(得分:3)

现场注入更加困难,因为必然会有反射;例如,如果您使用构造函数注入测试类,则只需创建模拟依赖项并将它们传递给new。直接写入私人领域需要大量的簿记。

然而,请注意,这个谈话已经超过四年了。正如您所展示的那样,从那时起,依赖注入工具(用于测试和生产)已经走过了漫长的道路,@Inject现在是官方的Java标准。您可以使用测试框架为您处理所有反射,并使用注入的依赖项轻松测试对象。<​​/ p>