Added: Injectors created by the @Guice annotation are now shared at the <test> level
diff --git a/CHANGES.txt b/CHANGES.txt
index fb6ba86..b56a146 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,6 +2,8 @@
Added: xmlpathinjar to the TestNG ant task
Added: TestNG can now invoke package protected constructors
+Added: Injectors created by the @Guice annotation are now shared at the <test> level
+Fixed: https://github.com/cbeust/testng/issues/57 Allow usage of package protected constructor of test classes
===========================================================================
diff --git a/src/main/java/org/testng/ITestContext.java b/src/main/java/org/testng/ITestContext.java
index d5f0ed3..ccb68cf 100644
--- a/src/main/java/org/testng/ITestContext.java
+++ b/src/main/java/org/testng/ITestContext.java
@@ -1,9 +1,13 @@
package org.testng;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
import org.testng.xml.XmlTest;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
/**
@@ -112,4 +116,10 @@
* @return the current XmlTest.
*/
public XmlTest getCurrentXmlTest();
+
+ public List<Module> getGuiceModules(Class<? extends Module> cls);
+ public void addGuiceModule(Class<? extends Module> cls, Module module);
+
+ public Injector getInjector(List<Module> moduleInstances);
+ public void addInjector(List<Module> moduleInstances, Injector injector);
}
diff --git a/src/main/java/org/testng/TestRunner.java b/src/main/java/org/testng/TestRunner.java
index f8c7924..ae12022 100644
--- a/src/main/java/org/testng/TestRunner.java
+++ b/src/main/java/org/testng/TestRunner.java
@@ -1,5 +1,8 @@
package org.testng;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.internal.Attributes;
@@ -57,7 +60,9 @@
*
* @author Cedric Beust, Apr 26, 2004
*/
-public class TestRunner implements ITestContext, ITestResultNotifier, IThreadWorkerFactory<ITestNGMethod> {
+public class TestRunner
+ implements ITestContext, ITestResultNotifier, IThreadWorkerFactory<ITestNGMethod>
+{
/* generated */
private static final long serialVersionUID = 4247820024988306670L;
private ISuite m_suite;
@@ -1797,4 +1802,34 @@
return m_attributes.removeAttribute(name);
}
+ private Map<Class<? extends Module>, List<Module>> m_guiceModules = Maps.newHashMap();
+
+ @Override
+ public List<Module> getGuiceModules(Class<? extends Module> cls) {
+ List<Module> result = m_guiceModules.get(cls);
+ return result;
+ }
+
+ @Override
+ public void addGuiceModule(Class<? extends Module> cls, Module module) {
+ List<Module> l = m_guiceModules.get(cls);
+ if (l == null) {
+ l = Lists.newArrayList();
+ m_guiceModules.put(cls, l);
+ }
+ l.add(module);
+ }
+
+ private Map<List<Module>, Injector> m_injectors = Maps.newHashMap();
+
+ @Override
+ public Injector getInjector(List<Module> moduleInstances) {
+ return m_injectors .get(moduleInstances);
+ }
+
+ @Override
+ public void addInjector(List<Module> moduleInstances, Injector injector) {
+ m_injectors.put(moduleInstances, injector);
+ }
+
} // TestRunner
diff --git a/src/main/java/org/testng/internal/ClassImpl.java b/src/main/java/org/testng/internal/ClassImpl.java
index dda4d58..785770c 100755
--- a/src/main/java/org/testng/internal/ClassImpl.java
+++ b/src/main/java/org/testng/internal/ClassImpl.java
@@ -1,5 +1,6 @@
package org.testng.internal;
+import com.google.inject.Injector;
import com.google.inject.Module;
import org.testng.IClass;
@@ -136,14 +137,27 @@
moduleInstances.add(module);
}
- return com.google.inject.Guice.createInjector(moduleInstances).getInstance(m_class);
+ // Reuse the previous injector, if any
+ Injector injector = m_testContext.getInjector(moduleInstances);
+ if (injector == null) {
+ injector = com.google.inject.Guice.createInjector(moduleInstances);
+ m_testContext.addInjector(moduleInstances, injector);
+ }
+ return injector.getInstance(m_class);
}
private Module[] getModules(Guice guice, Class<?> testClass) {
List<Module> result = Lists.newArrayList();
for (Class<? extends Module> moduleClass : guice.modules()) {
try {
- result.add(moduleClass.newInstance());
+ List<Module> modules = m_testContext.getGuiceModules(moduleClass);
+ if (modules != null && modules.size() > 0) {
+ result.addAll(modules);
+ } else {
+ Module instance = moduleClass.newInstance();
+ result.add(instance);
+ m_testContext.addGuiceModule(moduleClass, instance);
+ }
} catch (InstantiationException e) {
throw new TestNGException(e);
} catch (IllegalAccessException e) {
diff --git a/src/test/java/test/guice/Guice1Test.java b/src/test/java/test/guice/Guice1Test.java
new file mode 100644
index 0000000..d4e413e
--- /dev/null
+++ b/src/test/java/test/guice/Guice1Test.java
@@ -0,0 +1,23 @@
+package test.guice;
+
+import com.google.inject.Inject;
+
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import test.SimpleBaseTest;
+
+@Guice(modules = GuiceExampleModule.class)
+public class Guice1Test extends SimpleBaseTest {
+ static ISingleton m_object;
+
+ @Inject
+ ISingleton m_singleton;
+
+ @Test
+ public void singletonShouldWork() {
+ m_singleton.doSomething();
+ m_object = m_singleton;
+ }
+
+}
diff --git a/src/test/java/test/guice/Guice2Test.java b/src/test/java/test/guice/Guice2Test.java
new file mode 100644
index 0000000..ebe15f8
--- /dev/null
+++ b/src/test/java/test/guice/Guice2Test.java
@@ -0,0 +1,22 @@
+package test.guice;
+
+import com.google.inject.Inject;
+
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import test.SimpleBaseTest;
+
+@Guice(modules = GuiceExampleModule.class)
+public class Guice2Test extends SimpleBaseTest {
+ static ISingleton m_object;
+
+ @Inject
+ ISingleton m_singleton;
+
+ @Test
+ public void singletonShouldWork() {
+ m_object = m_singleton;
+ }
+
+}
diff --git a/src/test/java/test/guice/GuiceTest.java b/src/test/java/test/guice/GuiceTest.java
index 4214072..452ef42 100644
--- a/src/test/java/test/guice/GuiceTest.java
+++ b/src/test/java/test/guice/GuiceTest.java
@@ -1,21 +1,23 @@
package test.guice;
-import com.google.inject.Inject;
-
-import org.testng.annotations.Guice;
+import org.testng.TestNG;
import org.testng.annotations.Test;
+import junit.framework.Assert;
+
import test.SimpleBaseTest;
-@Guice(modules = GuiceExampleModule.class)
public class GuiceTest extends SimpleBaseTest {
- @Inject
- ISingleton m_singleton;
-
@Test
- public void singletonShouldWork() {
- m_singleton.doSomething();
- }
+ public void guiceTest() {
+ TestNG tng = create(new Class[] { Guice1Test.class, Guice2Test.class});
+ Guice1Test.m_object = null;
+ Guice2Test.m_object = null;
+ tng.run();
+ Assert.assertNotNull(Guice1Test.m_object);
+ Assert.assertNotNull(Guice2Test.m_object);
+ Assert.assertEquals(Guice1Test.m_object, Guice2Test.m_object);
+ }
}