I have been trying hard to get Guice, TestNG and Dropwizard to play well with each other. Essentially I am bootstrapping Guice to Dropwizard using the dropwizard hubspot artifacts like code below.
All my resources etc. are getting properly injected. However, when I invoke any of the TestNG tests programmatically and try to inject the AutomationExperimentConfiguration class then
TestNG is taking over Guice and instantiating a new instance of the AutomationExperimentConfiguration. Has anyone run into this? My sample code is below.
public class AutomationExperimentApplication extends Application<AutomationExperimentConfiguration> {
public static void main(final String[] args) throws Exception {
new AutomationExperimentApplication().run(args);
}
@Override
public String getName() {
return "automationexperiement";
}
/**
* Using the GuiceBundle with autoConfig = true makes adding new resources super simple.
* param bootstrap
*/
@Override
public void initialize(final Bootstrap<AutomationExperimentConfiguration> bootstrap) {
bootstrap.setConfigurationSourceProvider(
new SubstitutingSourceProvider(
bootstrap.getConfigurationSourceProvider(),
new EnvironmentVariableSubstitutor(false)
)
);
GuiceBundle<AutomationExperimentConfiguration> guiceBundle = GuiceBundle.<AutomationExperimentConfiguration>newBuilder()
.addModule(new AutomationExperimentModule())
.enableAutoConfig(getClass().getPackage().getName())
.setConfigClass(AutomationExperimentConfiguration.class)
.build();
bootstrap.addBundle(guiceBundle);
}
@Override
public void run(final AutomationExperimentConfiguration configuration, final Environment environment) {
}
}
public class AutomationExperimentModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
@Named("testURLs")
public Map<URLScheme, String> provideURLScheme(AutomationExperimentConfiguration configuration) {
return configuration.getTestURLs();
}
@Provides
@Named("testConfig")
public AutomationExperimentConfiguration provideConfiguration(AutomationExperimentConfiguration configuration) {
return configuration;
}
}
@Guice(modules = AutomationExperimentModule.class)
public class BaseTest {
protected Map<URLScheme, String> testURLs;
protected AutomationExperimentConfiguration configuration;
@Inject
public void setConfiguration(@Named("testURLs") Map<URLScheme, String> testURLs) {
this.testURLs = testURLs;
}
@Inject
public void setConfig(@Named("testConfig")AutomationExperimentConfiguration configuration) {
this.configuration = configuration;
}
}
public class IntegrationTest extends BaseTest {
private static final Logger LOGGER = LoggerFactory.getLogger(IntegrationTest.class);
@BeforeClass
public void setUp() throws Exception {
LOGGER.info("Inside setUp");
}
@AfterClass
public void tearDown() throws Exception {
LOGGER.info("Inside tearDown");
}
@BeforeMethod
public void setUpTest() throws Exception {
LOGGER.info("Inside setUpTest");
}
@Test
public void testHelloWorld() throws Exception {
LOGGER.info("Inside testHelloWorld: " + configuration.getEnvironmentURLs().get("stage").get("baseURL")); //Configuration here is all messed up because TestNG Guice has instantiated it vs using the dropwizard instance of Guice.
}
}
@Path("/testsuite")
@Produces(MediaType.APPLICATION_JSON)
public class TestNgResource {
private static final Logger LOGGER = LoggerFactory.getLogger(TestNgResource.class);
AutomationExperimentConfiguration configuration;
@Inject
TestNgResource(AutomationExperimentConfiguration configuration) {
this.configuration = configuration;
LOGGER.info("Base URL: " + configuration.getTestURLs().get(URLScheme.SatelliteURL));
}
@POST
public void runSuite(@QueryParam("suiteName") String suiteName) {
LOGGER.info("URLs are: " + configuration.getEnvironmentURLs().get("stage").get("baseURL")); // Configuration here is fine.
List<String> suites = Lists.newArrayList();
suites.add("src/main/resources/testng_smoke.xml");
TestNG testng = new TestNG();
testng.setTestSuites(suites);
testng.run();
}
}