在没有 main 方法的情况下为基本字段注入配置 guice

Configuring guice for basic field injection without a main method

我最近一直在研究 guice,并且需要在我的自动化框架中进行一些字段注入。例如,我有一个 EnvironmentSetter class,我想将其作为单例注入到其他各种 classes.

1) 我没有标准的 main 方法,所以我正在努力研究如何 bootstrap 正确引导。我正在使用 testNG,所以我正在尝试 bootstrap 使用像这样的静态块:

public class TestExecutionListener implements IExecutionListener {
    private static final Logger LOG = LogManager.getLogger(TestExecutionListener.class);


   static {
            Bootstrapper.BootStrapGuiceDI();
    }

    @Inject
    EnvironmentSetter env;

    @Override
    public void onExecutionStart() {
        LOG.debug("Starting test run!");
        env.generateEnvironmentProperties();
    }

    @Override
    public void onExecutionFinish() {
        LOG.debug("Finished test run!");
    }

}

我还创建了以下内容:

public class EnvironmentSetterModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(EnvironmentSetter.class);
    }
}

这就是我从静态块调用的内容:

public static void BootStrapGuiceDI() {
    LOG.debug("Bootstrapping");
    Injector injector = Guice.createInjector(new Module());
    EnvironmentSetter env = injector.getInstance(EnvironmentSetter.class);
}

在这种情况下,我注入的 EnvironmentSetter env 仍然是 null,我需要什么才能有效地使用它?

EnvironmentSetter class:

public class EnvironmentSetter implements IEnvironmentPopulator {
    private static final Logger LOG = LogManager.getLogger(EnvironmentSetter.class);

    PropertyProvider properties = PropertyProvider.INSTANCE;


    public EnvironmentSetter() {

    }

    public void generateEnvironmentProperties() {
        Properties props = new Properties();
        properties.getAllProperties().forEach((k,v) -> props.setProperty(k,v));
        try {
            File f = new File("target\allure-results\environment.properties");
            f.getParentFile().mkdirs();
            f.createNewFile();
            props.store(new FileOutputStream(f), "Allure Environment Properties");
        } catch(IOException ioe) {
            LOG.fatal(ioe);
        }
    }
}

您应该添加在 createInejector 方法中创建的模块,而不是 new Module();

public static void BootStrapGuiceDI() {
    LOG.debug("Bootstrapping");
    // Injector injector = Guice.createInjector(new Module()); // use your module (EnvironmentSetterModule )
    // Now, guice will be able to "see" your class
    Injector injector = Guice.createInjector(new EnvironmentSetterModule());
    EnvironmentSetter env = injector.getInstance(EnvironmentSetter.class);
}

此外,仅引导它不会自动将所有字段注入测试 classes 中的所有字段,要在测试中注入,您可以使用新的 Injector 并注入测试成员class injectMembers(this),其中 this 将引用您的测试实例,因此必须在某个设置块上执行。 查看有关如何在 Test => Guice BoundFields

上正确引导它的 guice 文档

如果您使用的是 TestNG,则有一种使用注释 guiceModule 来执行此操作的更简单的方法。基本上,TestNG 会为您进行引导,您需要做的就是在注释中提及 Guice 模块名称。示例:

@Test(guiceModule = GuiceExampleModule.class)
public class GuiceTest {

  @Inject
  ExternalDependency dependency;

  @Test
  public void singletonShouldWork() {
    Assert.assertTrue(true, dependency.shouldExecute());
  }
}

在 Cedric 的博文中阅读更多相关信息:TestNG and Guice: a match made in heaven