我如何测试Guice注射?
我向Google Guice提供了连接我的物品的责任。 但是,我如何测试绑定是否运行良好?
例如,假设我们有一个具有依赖关系B
A
类。 如何测试B是否正确注入?
class A { private B b; public A() {} @Inject public void setB(B b) { this.b = b } }
请注意, A
没有getB()
方法,我想断言Ab
不是null
。
对于任何复杂的Guice项目,您应该添加测试以确保可以使用这些模块来创建类。 在你的例子中,如果B是Guice无法弄清楚如何创建的类型,那么Guice将无法创建A.如果A不需要启动服务器但是在服务器处理时需要请求,这会导致问题。
在我的项目中,我为非平凡模块编写测试。 对于每个模块,我使用requireBinding()来声明模块所需的绑定但未定义。 在我的测试中,我使用被测模块创建了一个Guice注入器,另一个模块提供了所需的绑定。 这是使用JUnit4和JMock的示例:
/** Module that provides LoginService */ public class LoginServiceModule extends AbstractModule { @Override protected void configure() { requireBinding(UserDao.class); } @Provides LoginService provideLoginService(UserDao dao) { ... } } @RunWith(JMock.class) public class LoginServiceModuleTest { private final Mockery context = new Mockery(); @Test public void testModule() { Injector injector = Guice.createInjector( new LoginServiceModule(), new ModuleDeps()); // next line will throw an exception if dependencies missing injector.getProvider(LoginService.class); } private class ModuleDeps extends AbstractModule { private final UserDao fakeUserDao; public ModuleDeps() { fakeUserDao = context.mock(UserDao.class); } @Override protected void configure() {} @Provides Server provideUserDao() { return fakeUserDao; } } }
请注意该测试仅询问提供者。 这足以确定Guice可以解决绑定问题。 如果LoginService是由提供程序方法创建的,则此测试不会测试提供程序方法中的代码。
此测试也不会测试您是否将正确的内容绑定到UserDao
,或者UserDao
范围是否正确。 有人会争辩说,那些类型的东西很少值得检查; 如果有问题,它会发生一次。 你应该“测试,直到恐惧变成无聊。”
我发现模块测试很有用,因为我经常添加新的注入点,并且很容易忘记添加绑定。
requireBinding()
调用可以帮助Guice在返回注入器之前捕获缺失的绑定! 在上面的例子中,如果requireBinding()
调用不存在,测试仍然可以工作,但我喜欢它们,因为它们用作文档。
对于更复杂的模块(比如我的根模块),我可能会使用Modules.override()来覆盖我在测试时不想要的绑定(例如,如果我想validation我的根对象是否要创建,我可能不会不希望它创建一个将连接到数据库的对象。 对于简单项目,您可能只测试顶级模块。
请注意,除非使用@Nullable
注释字段,否则Guice 不会注入空值 ,因此您很少需要validation注入的对象在测试中是否为空。 事实上,当我使用@Inject
注释构造函数时,我不打算检查参数是否为null
(事实上,我的测试经常在构造函数中注入null
以保持测试简单)。
测试配置的另一种方法是使用测试套件来端到端测试您的应用程序。 虽然端到端测试名义上测试用例,但他们间接检查您的应用程序是否配置正确,(所有依赖关系都是有线的等)。 另一方面,unit testing应该只关注域,而不是关注部署代码的上下文。
我也同意NamshubWriter的回答。 我不反对检查配置的测试,只要它们被分组到unit testing的单独测试套件中。
恕我直言,你不应该测试。 谷歌Guice家伙有unit testing断言注射按预期工作 – 毕竟,这就是Guice的目的。 您应该只为自己的代码(A和B)编写测试。
我认为你不应该测试私人成员的设置。 最好测试你class级的公共界面。 如果不注入成员“b”,你可能会得到一个执行测试的NullPointerException,这应该是很多警告。