文档

§使用 Guice 进行测试

如果您使用 Guice 进行 依赖注入,那么您可以直接配置组件和应用程序的创建方式以进行测试。这包括添加额外的绑定或覆盖现有绑定。

§GuiceApplicationBuilder

GuiceApplicationBuilder 提供了一个构建器 API,用于配置依赖注入和 Application 的创建。

§导入

使用 Guice 构建应用程序所需的主要导入项是

import play.Application;
import play.inject.guice.GuiceApplicationBuilder;

§环境

可以指定 Environment 或环境的某些部分,例如应用程序的根路径、模式或类加载器。配置的环境将用于加载应用程序配置,它将在加载模块时使用,并在从 Play 模块派生绑定时传递,并且它将可注入到其他组件中。

Application application =
    new GuiceApplicationBuilder()
        .load(
            new play.api.inject.BuiltinModule(),
            new play.inject.BuiltInModule(),
            new play.api.i18n.I18nModule(),
        .in(new Environment(new File("path/to/app"), classLoader, Mode.TEST))
        .build();
Application application =
    new GuiceApplicationBuilder()
        .load(
            new play.api.inject.BuiltinModule(),
            new play.inject.BuiltInModule(),
            new play.api.i18n.I18nModule(),
        .in(new File("path/to/app"))
        .in(Mode.TEST)
        .in(classLoader)
        .build();

§配置

可以添加额外的配置。此配置将始终添加到为应用程序自动加载的配置中。当使用现有键时,将优先使用新的配置。

Config extraConfig = ConfigFactory.parseMap(ImmutableMap.of("a", 1));
Map<String, Object> configMap = ImmutableMap.of("b", 2, "c", "three");

Application application =
    new GuiceApplicationBuilder()
        .configure(extraConfig)
        .configure(configMap)
        .configure("key", "value")
        .build();

也可以覆盖从应用程序环境自动加载配置。这将完全替换应用程序配置。例如

Application application =
    new GuiceApplicationBuilder()
        .withConfigLoader(env -> ConfigFactory.load(env.classLoader()))
        .build();

§绑定和模块

用于依赖注入的绑定是完全可配置的。构建器方法支持 Play 模块和绑定 以及 Guice 模块。

§附加绑定

可以通过 Play 模块、Play 绑定或 Guice 模块添加附加绑定

import static play.inject.Bindings.bind;
Application application =
    new GuiceApplicationBuilder()
        .bindings(new ComponentModule())
        .bindings(bind(Component.class).to(DefaultComponent.class))
        .build();

§覆盖绑定

可以使用 Play 绑定或提供绑定的模块来覆盖绑定。例如

Application application =
    new GuiceApplicationBuilder()
        .overrides(bind(Component.class).to(MockComponent.class))
        .build();

§禁用模块

可以通过类名禁用任何已加载的模块

Application application =
    new GuiceApplicationBuilder()
        .disable(ComponentModule.class)
        .build();

§已加载的模块

模块会根据 play.modules.enabled 配置从类路径中自动加载。可以覆盖此默认模块加载。例如

import play.inject.guice.Guiceable;
Application application =
    new GuiceApplicationBuilder()
        .load(
            Guiceable.modules(
                new play.api.inject.BuiltinModule(),
                new play.api.i18n.I18nModule(),
                new play.api.mvc.CookiesModule(),
                new play.inject.BuiltInModule()),
            Guiceable.bindings(bind(Component.class).to(DefaultComponent.class)))
        .build();

§GuiceInjectorBuilder

GuiceInjectorBuilder 提供了一个构建器 API,用于更一般地配置 Guice 依赖注入。此构建器不会像 GuiceApplicationBuilder 一样从环境中自动加载配置或模块,而是提供一个完全干净的状态来添加配置和绑定。这两个构建器的通用接口可以在 GuiceBuilder 中找到。将创建一个 Play Injector。以下是如何使用注入器构建器实例化组件的示例

import play.inject.Injector;
import play.inject.guice.GuiceInjectorBuilder;
import static play.inject.Bindings.bind;
Injector injector =
    new GuiceInjectorBuilder()
        .configure("key", "value")
        .bindings(new ComponentModule())
        .overrides(bind(Component.class).to(MockComponent.class))
        .injector();

Component component = injector.instanceOf(Component.class);

§在功能测试中覆盖绑定

以下是用模拟组件替换组件以进行测试的完整示例。让我们从一个组件开始,该组件具有默认实现和用于测试的模拟实现

public interface Component {
  String hello();
}
public class DefaultComponent implements Component {
  public String hello() {
    return "default";
  }
}
public class MockComponent implements Component {
  public String hello() {
    return "mock";
  }
}

此组件使用模块自动加载

import com.google.inject.AbstractModule;

public class ComponentModule extends AbstractModule {
  protected void configure() {
    bind(Component.class).to(DefaultComponent.class);
  }
}

该组件在控制器中使用

import play.mvc.*;
import javax.inject.Inject;
import javax.inject.Singleton;

@Singleton
public class Application extends Controller {

  private final Component component;

  @Inject
  public Application(Component component) {
    this.component = component;
  }

  public Result index() {
    return ok(component.hello());
  }
}

要构建一个在 功能测试 中使用的 Application,我们可以简单地覆盖组件的绑定

import play.Application;
import play.inject.guice.GuiceApplicationBuilder;
import static play.inject.Bindings.bind;
Application application =
    new GuiceApplicationBuilder()
        .overrides(bind(Component.class).to(MockComponent.class))
        .build();

此应用程序可与测试助手(如 runningWithApplication)一起使用。

下一步:使用数据库进行测试


在此文档中发现错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。