Open avarabyeu opened 11 years ago
IModuleFactory lets you return the module you want, just return the same one all the time and the same injector will be used to instantiate all your test classes.
Or am I missing something?
Absolutely right. But there is no possibility to share Injectors between tests. Each test creates new injector and puts it into test context. New test == new test context, so there is no way to cache injectors somewhere... org.testng.internal.ClassImpl.getInstanceFromGuice()
One thing i've found out as workaround - we can create base class for all tests and inject class members from constructor.
public class BaseTest { public BaseTest() { GuiceInjector.getInstance().getInjector().injectMembers(this); } }
So, we can create some singleton with injector inside ('GuiceInjector') and use it for all tests.
Cedric, would you mind if I fix that? I can fork repo and provide solution.
Sure, go ahead.
Cédric
On Thu, Jun 20, 2013 at 1:25 PM, Andrei Varabyeu notifications@github.comwrote:
Cedric, would you mind if I fix that? I can fork repo and provide solution.
— Reply to this email directly or view it on GitHubhttps://github.com/cbeust/testng/issues/398#issuecomment-19780709 .
@avarabyeu Do you remember the Pull Request or Commit for this change?
@avarabyeu, @cbeust Hi I'm facing the same issue where multiple injectors are getting created for different tests belonging to the same suite, and I need one injector instance for all tests. Was this solution implemented?
@diegovegaz As i remember, i've just created injector manually and utilized it in ObjectFactory
@diegovegaz @avarabyeu - Would you be able to help share a sample that I can use to reproduce this issue ? Based on what I find, i can try addressing this issue or atleast coming back with a proper way of getting this done using TestNG as a sample.
I have a testng.xml with the suite having multiple tests which are configured to run in parallel. For all TestNG classes, there is a base class, which is annotated with @Guice(module = xxx).
//Below is the base test class which uses the Guice module for DI
@Guice(modules = {XXXTestsGuiceModule.class})
public class XXXBaseTest{
@Inject
@Named("testObj")
private TestObj testObj;
}
//Below is the module definition
public class XXXTestsGuiceModule extends AbstractModule{
@Override
protected void configure() {
bind(TestObj.class)
.annotatedWith(Names.named("testObj"))
.to(TestObj.class)
.in(Scopes.SINGLETON);
}
}
//Below is the dependency
@Slf4j
public class TestObj {
public TestObj() {
log.debug("creating test object instance");
}
}
When the tests start, I see the above log statement ("creating test object instance") printed more than once.
From https://groups.google.com/d/msg/testng-users/5-Nso0oY0yY/uXZYb1wNw1AJ, found this mentioned by Cedric:
"Whenever you use a @Guice annotation on one of your test classes, TestNG will create an injector with the modules your provided"
Can you let me know which version of TestNG has the fix? I am currently using 6.8
@krmahadevan, shared the sample above, please let me know if you have a solution or workaround for the same.
@cbeust , sorry for the late mention, however, have you considered using scopes? (e.g. SuiteScope, TestScope)
For instance, the current IModuleFactory
supplies ITestContext context, Class<?> testClass
via factory arguments.
However, it could provide the very same information via Guice bindings. Then IModuleFactory
won't really be needed.
WDYT?
This seems to be a relevant case: https://groups.google.com/g/testng-users/c/KWqo4l4PeU4
Unable to create one Guice injector for all tests or suites. I would suggest to introduce some GuiceInjectorFactory to be able to manage and cache injectors by yourself. Current functionality may be decoupled to some DefaultInjectorFactory or something like that. New factories may be accessible from org.testng.TestNG.