如何测试桂皮注射?
我把连接对象的责任交给了 Google Guice。但是,如何测试绑定是否正常工作?
例如,假设我们有一个具有依赖关系的类。如何测试B是否正确注入?A
B
class A {
private B b;
public A() {}
@Inject
public void setB(B b) {
this.b = b
}
}
请注意,没有方法,我想断言它不是。A
getB()
A.b
null
我把连接对象的责任交给了 Google Guice。但是,如何测试绑定是否正常工作?
例如,假设我们有一个具有依赖关系的类。如何测试B是否正确注入?A
B
class A {
private B b;
public A() {}
@Inject
public void setB(B b) {
this.b = b
}
}
请注意,没有方法,我想断言它不是。A
getB()
A.b
null
对于任何复杂的 Guice 项目,都应添加测试以确保这些模块可用于创建类。在您的示例中,如果 B 是 Guice 无法弄清楚如何创建的类型,则 Guice 将无法创建 A。如果启动服务器不需要 A,但在服务器处理请求时需要 A,则会导致问题。
在我的项目中,我为重要的模块编写测试。对于每个模块,我使用 requireBinding() 来声明模块需要但不定义的绑定。在我的测试中,我使用被测模块创建一个 Guice 注入器,并使用另一个提供所需绑定的模块创建一个 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
我发现Module测试很有用,因为我经常添加新的注入点,而且很容易忘记添加绑定。
这些调用可以帮助 Guice 在返回注入器之前捕获缺少的绑定!在上面的示例中,如果调用不存在,测试仍然有效,但我喜欢使用它们,因为它们充当文档。requireBinding()
requireBinding()
对于更复杂的模块(如我的根模块),我可能会使用 Modules.override() 在测试时覆盖我不想要的绑定(例如,如果我想验证是否要创建根对象,我可能不希望它创建将连接到数据库的对象)。对于简单项目,您可能只测试顶级模块。
请注意,Guice 不会注入 null,除非字段带有注释,因此您很少需要验证注入的对象在测试中是否为非 null。事实上,当我用构造函数注释时,我懒得检查参数是否是(事实上,我的测试经常注入构造函数以保持测试简单)。@Nullable
@Inject
null
null
测试配置的另一种方法是使用测试套件来端到端测试应用。尽管端到端测试名义上测试用例,但它们间接检查你的应用配置是否正确(所有依赖项是否都已连接,等等)。另一方面,单元测试应仅关注域,而不是部署代码的上下文。
我也同意NamshubWriter的答案。我不反对检查配置的测试,只要它们分组到单元测试的单独测试套件中即可。