java - 如何测试 Guice 注入(inject)?

标签 java testing dependency-injection guice

我让 Google Guice 负责连接我的对象。但是,如何测试绑定(bind)是否正常工作?

例如,假设我们有一个类A,它有一个依赖B。如何测试 B 是否正确注入(inject)?

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 时需要 A请求,这会导致问题。

在我的项目中,我为重要的模块编写测试。对于每个模块,我使用 requireBinding()声明模块需要但未定义的绑定(bind)。在我的测试中,我使用被测模块和另一个提供所需绑定(bind)的模块创建了一个 Guice 注入(inject)器。下面是一个使用 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 可以解决绑定(bind)问题。如果 LoginService 是由 provider 方法创建的,则此测试不会测试 provider 方法中的代码。

此测试也不会测试您是否将正确的东西绑定(bind)到 UserDao,或者 UserDao 的范围是否正确。有些人会争辩说,这些类型的东西很少值得检查。如果有问题,它会发生一次。你应该“测试直到恐惧变成无聊。”

我发现模块测试很有用,因为我经常添加新的注入(inject)点,而且很容易忘记添加绑定(bind)。

requireBinding() 调用可以帮助 Guice 在返回注入(inject)器之前捕获丢失的绑定(bind)!在上面的示例中,如果 requireBinding() 调用不存在,测试仍然可以工作,但我喜欢使用它们,因为它们用作文档。

对于更复杂的模块(比如我的根模块),我可能会使用 Modules.override()覆盖我在测试时不想要的绑定(bind)(例如,如果我想验证我的根对象是否被创建,我可能不希望它创建一个将连接到数据库的对象)。对于简单的项目,您可能只测试顶级模块。

请注意,Guice will not inject nulls除非该字段用 @Nullable 注释,因此您很少需要在测试中验证注入(inject)的对象是否为非空。事实上,当我用 @Inject 注释构造函数时,我并不费心检查参数是否为 null (事实上,我的测试经常注入(inject) null 进入构造函数以保持测试简单)。

关于java - 如何测试 Guice 注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2448013/

相关文章:

java - 为什么 Float.valueOf ("2.7") > 2.7 给我 true ?

java - WebSphere + RAD + 标签库

c# - MVC5 和 Ninject :Parameterless constructor error

reactjs - 使用 Jest 和 Enzyme 测试 React 组件 : where to test whether component props were given

php - Symfony2 服务容器 - 将普通参数传递给服务构造函数

java - 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

Java Netty : memory leak problem with DefaultChannelHandlerContext

java - 通知点击事件而不显示 Activity ?

testing - 不允许PUT-带有Swagger的REST保证

java - 在maven编译期间跳过测试