32

我让 Google Guice 负责连接我的对象。但是,我如何测试绑定是否运行良好?

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

class A {
    private B b;
    public A() {}

    @Inject
    public void setB(B b) {
        this.b = b
    }
}

请注意,A没有getB()方法,我想断言A.b不是null

4

4 回答 4

46

对于任何复杂的 Guice 项目,您应该添加测试以确保模块可以用于创建您的类。在您的示例中,如果 B 是 Guice 无法弄清楚如何创建的类型,那么 Guice 将无法创建 A。如果启动服务器不需要 A,但在您的服务器处理 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()来覆盖我在测试时不想要的绑定(例如,如果我想验证我的根对象是否被创建,我可能不会'不希望它创建一个将连接到数据库的对象)。对于简单的项目,您可能只测试顶级模块。

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

于 2010-04-17T20:40:20.750 回答
4

另一种测试您的配置的方法是拥有一个测试套件来测试您的应用程序端到端。尽管端到端测试名义上是测试用例,但它们会间接检查您的应用程序是否配置正确(所有依赖项是否已连接等)。另一方面,单元测试应该只关注域,而不是部署代码的上下文。

我也同意 NamshubWriter 的回答。我不反对检查配置的测试,只要它们被分组在一个单独的测试套件中进行单元测试。

于 2010-11-02T15:52:22.430 回答
2

恕我直言,您不应该对此进行测试。Google Guice 的人有单元测试来断言注入按预期工作 - 毕竟,这就是 Guice 的设计目的。您应该只为自己的代码(A 和 B)编写测试。

于 2010-03-15T15:37:20.173 回答
0

我认为您不应该测试正在设置的私人成员。最好针对您的类的公共接口进行测试。如果不注入成员“b”,您可能会在执行测试时收到 NullPointerException,这应该是很多警告。

于 2010-03-15T15:00:42.643 回答