2 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.odlguice.inject.guice.testutils;
10 import com.google.inject.ConfigurationException;
11 import com.google.inject.Guice;
12 import com.google.inject.Injector;
13 import com.google.inject.Module;
14 import com.google.inject.Stage;
15 import java.util.Arrays;
16 import java.util.List;
17 import java.util.stream.Collectors;
18 import org.junit.rules.MethodRule;
19 import org.junit.runners.model.FrameworkMethod;
20 import org.junit.runners.model.Statement;
21 import org.opendaylight.odlguice.inject.PostFullSystemInjectionListener;
22 import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
25 * JUnit Rule which initializes Guice {@link Injector} for tests.
29 * public {@literal @}Rule GuiceRule guice = new GuiceRule(YourGuiceModule.class);
31 * {@literal @}Inject SomeClass someClass;
34 * @author Michael Vorburger.ch
36 public class GuiceRule implements MethodRule {
39 * Default Stage PRODUCTION.
40 * Note that this is different from Guice's DEVELOPMENT default.
41 * We do this to avoid having to declare bindings of Listeners asEagerSingleton(),
42 * because in typical OpenDaylight projects there are Listener classes which are not @Inject,
43 * but must still be created (so that they're registered).
44 * See <a href="https://github.com/google/guice/wiki/Bootstrap">Guice documentation</a>.
46 protected static final Stage DEFAULT_STAGE = Stage.PRODUCTION;
48 protected final Iterable<? extends Module> modules;
49 protected final Stage stage;
51 protected Injector injector;
53 public GuiceRule(Module... modules) {
54 this(DEFAULT_STAGE, modules);
57 protected GuiceRule(Stage stage, Module... modules) {
58 this.modules = Arrays.asList(modules);
63 public GuiceRule(Class<? extends Module>... moduleClasses) {
64 this.modules = createModules(Arrays.asList(moduleClasses));
65 this.stage = DEFAULT_STAGE;
68 private static Iterable<? extends Module> createModules(List<Class<? extends Module>> moduleClasses) {
69 return moduleClasses.stream().map(klass -> {
71 return klass.getConstructor().newInstance();
72 } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
73 throw new IllegalArgumentException("newInstance() failed: " + klass.getName(), e);
75 }).collect(Collectors.toList());
79 public Statement apply(Statement base, FrameworkMethod method, Object target) {
80 return new Statement() {
82 public void evaluate() throws Throwable {
93 protected void setUpGuice(Object target) {
94 injector = Guice.createInjector(stage, modules);
95 injector.injectMembers(target);
98 injector.getInstance(PostFullSystemInjectionListener.class).onFullSystemInjected();
99 } catch (ConfigurationException e) {
100 // It's OK if we didn't bind a PostFullSystemInjectionListener.
104 protected void tearDownGuice() {
105 if (injector != null) {
106 // http://code.mycila.com/guice/#3-jsr-250
108 injector.getInstance(CloseableInjector.class).close();
109 } catch (ConfigurationException e) {
110 throw new IllegalStateException("You forgot to either add GuiceRule(..., AnnotationsModule.class), "
111 + "or in your Module use an install(new AnnotationsModule()) with "
112 + AnnotationsModule.class.getName(), e);