--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.opendaylight.infrautils</groupId>
+ <artifactId>inject.guice.testutils</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.mycila.guice.extensions</groupId>
+ <artifactId>mycila-guice-jsr250</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.truth</groupId>
+ <artifactId>truth</artifactId>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils;
+
+import com.google.inject.AbstractModule;
+import com.mycila.guice.ext.closeable.CloseableModule;
+import com.mycila.guice.ext.jsr250.Jsr250Module;
+
+/**
+ * Guice module with built-in Mycila Guice Extensions for JSR-250 &
+ * Closeable support for {@literal @}PreDestroy & {@literal @}PostConstruct.
+ *
+ * @author Michael Vorburger
+ */
+public abstract class GuiceModule extends AbstractModule {
+
+ @Override
+ protected final void configure() {
+ install(new CloseableModule());
+ install(new Jsr250Module());
+ }
+
+ protected abstract void configureBindings();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.Stage;
+import com.mycila.guice.ext.closeable.CloseableInjector;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * JUnit Rule which initializes Guice {@link Injector} for tests.
+ *
+ * <p>Usage:
+ * <pre>
+ * public {@literal @}Rule GuiceRule guice = new GuiceRule(YourGuiceModule.class);
+ *
+ * {@literal @}Inject SomeClass someClass;
+ * </pre>
+ *
+ * @author Michael Vorburger
+ */
+public class GuiceRule implements MethodRule {
+
+ /**
+ * Default Stage PRODUCTION.
+ * Note that this is different from Guice's DEVELOPMENT default.
+ * We do this to avoid having to declare bindings of Listeners asEagerSingleton(),
+ * because in typical OpenDaylight projects there are Listener classes which are not @Inject,
+ * but must still be created (so that they're registered).
+ * @see <a href="https://github.com/google/guice/wiki/Bootstrap">Guice documentation</a>.
+ */
+ protected static final Stage DEFAULT_STAGE = Stage.PRODUCTION;
+
+ protected final Iterable<? extends Module> modules;
+ protected final Stage stage;
+
+ protected Injector injector;
+
+ public GuiceRule(Module... modules) {
+ this(DEFAULT_STAGE, modules);
+ }
+
+ protected GuiceRule(Stage stage, Module... modules) {
+ this.modules = Arrays.asList(modules);
+ this.stage = stage;
+ }
+
+ @SafeVarargs
+ public GuiceRule(Class<? extends Module>... moduleClasses) {
+ this.modules = createModules(Arrays.asList(moduleClasses));
+ this.stage = DEFAULT_STAGE;
+ }
+
+ protected Iterable<? extends Module> createModules(List<Class<? extends Module>> moduleClasses) {
+ return moduleClasses.stream().map(klass -> {
+ try {
+ return klass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new IllegalArgumentException("newInstance() failed: " + klass.getName(), e);
+ }
+ }).collect(Collectors.toList());
+ }
+
+ @Override
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ setUpGuice(target);
+ base.evaluate();
+ } finally {
+ tearDownGuice();
+ }
+ }
+ };
+ }
+
+ protected void setUpGuice(Object target) {
+ injector = Guice.createInjector(stage, modules);
+ injector.injectMembers(target);
+ }
+
+ protected void tearDownGuice() {
+ if (injector != null) {
+ // http://code.mycila.com/guice/#3-jsr-250
+ injector.getInstance(CloseableInjector.class).close();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils.tests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import javax.inject.Inject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceModule;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
+
+/**
+ * Example Guice Test using the {@link GuiceRule} & {@link GuiceModule}.
+ *
+ * @author Michael Vorburger
+ */
+public class ExampleGuiceRuleTest {
+
+ public @Rule GuiceRule guice = new GuiceRule(TestModule.class);
+
+ @Inject SomeClassWithPostConstruct someClass;
+
+ @Test public void testGuiceWithRule() {
+ assertThat(someClass.isInit).named("isInit").isTrue();
+ }
+
+ public static class TestModule extends GuiceModule {
+ @Override
+ protected void configureBindings() {
+ bind(SomeClassWithPostConstruct.class);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils.tests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.mycila.guice.ext.closeable.CloseableModule;
+import com.mycila.guice.ext.jsr250.Jsr250Module;
+import org.junit.Test;
+
+/**
+ * Example Guice Test without using Rule, just for illustration.
+ *
+ * @see ExampleGuiceRuleTest
+ *
+ * @author Michael Vorburger
+ */
+public class ExamplePureGuiceTest {
+
+ @Test
+ public void testPostConstruct() {
+ Injector injector = Guice.createInjector(new TestModule());
+ SomeClassWithPostConstruct someClass = injector.getInstance(SomeClassWithPostConstruct.class);
+ assertThat(someClass.isInit).named("isInit").isTrue();
+ }
+
+ static class TestModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ install(new CloseableModule());
+ install(new Jsr250Module());
+ bind(SomeClassWithPostConstruct.class).asEagerSingleton();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils.tests;
+
+import javax.annotation.PostConstruct;
+
+class SomeClassWithPostConstruct {
+
+ boolean isInit = false;
+
+ @PostConstruct
+ public void init() {
+ isInit = true;
+ }
+
+}
</build>
<dependencies>
- <!-- TODO Remove this when https://git.opendaylight.org/gerrit/#/c/44502/ is merged -->
<dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.truth</groupId>
+ <artifactId>truth</artifactId>
+ </dependency>
</dependencies>
</project>
<modules>
<module>inject</module>
+ <module>inject-guice-testutils</module>
</modules>
<!--