I have been recently looking into guice and have the need to have some field injection in my automation framework. For example I have an EnvironmentSetter class which I want to inject as a singleton to various other classes.
1) I do not have a standard main method, so I am struggling with how to bootstrap guice correctly. I am using testNG so I am attempting to bootstrap using a static block like so:
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!");
}
}
I have also created the following:
public class EnvironmentSetterModule extends AbstractModule {
@Override
protected void configure() {
bind(EnvironmentSetter.class);
}
}
and this is what I am calling from the static block:
public static void BootStrapGuiceDI() {
LOG.debug("Bootstrapping");
Injector injector = Guice.createInjector(new Module());
EnvironmentSetter env = injector.getInstance(EnvironmentSetter.class);
}
In this scenario, my injected EnvironmentSetter env is still null, what do I need in order to use this effectively?
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);
}
}
}
If you are using TestNG, there is a much more simple way to do this using the annotation guiceModule. Basically, TestNG does the bootstrapping for you and all you need to do is mention the Guice module name in the annotation. Example:
@Test(guiceModule = GuiceExampleModule.class)
public class GuiceTest {
@Inject
ExternalDependency dependency;
@Test
public void singletonShouldWork() {
Assert.assertTrue(true, dependency.shouldExecute());
}
}
Read more about this in Cedric's blogpost: TestNG and Guice: a match made in heaven