如何测试桂皮注射?

2022-09-01 07:37:26

我把连接对象的责任交给了 Google Guice。但是,如何测试绑定是否正常工作?

例如,假设我们有一个具有依赖关系的类。如何测试B是否正确注入?AB

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

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

请注意,没有方法,我想断言它不是。AgetB()A.bnull


答案 1

对于任何复杂的 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 是由提供程序方法创建的,则此测试不会测试提供程序方法中的代码。

此测试也不测试您是否将正确的内容绑定到 ,或者是否正确限定了作用域。有些人会争辩说,这类事情很少值得检查;如果有问题,就会发生一次。你应该“测试,直到恐惧变成无聊”。UserDaoUserDao

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

这些调用可以帮助 Guice 在返回注入器之前捕获缺少的绑定!在上面的示例中,如果调用不存在,测试仍然有效,但我喜欢使用它们,因为它们充当文档。requireBinding()requireBinding()

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

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


答案 2

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

我也同意NamshubWriter的答案。我不反对检查配置的测试,只要它们分组到单元测试的单独测试套件中即可。