/core/test/com/google/inject/MembersInjectorTest.java

https://code.google.com/ · Java · 287 lines · 218 code · 51 blank · 18 comment · 0 complexity · 69e6675085edb59b1a097d12dba66d2c MD5 · raw file

  1. /**
  2. * Copyright (C) 2009 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.inject;
  17. import static com.google.inject.Asserts.assertContains;
  18. import com.google.inject.name.Names;
  19. import com.google.inject.util.Providers;
  20. import junit.framework.AssertionFailedError;
  21. import junit.framework.TestCase;
  22. import java.util.concurrent.atomic.AtomicReference;
  23. /**
  24. * @author jessewilson@google.com (Jesse Wilson)
  25. */
  26. public class MembersInjectorTest extends TestCase {
  27. private static final A<C> uninjectableA = new A<C>() {
  28. @Override void doNothing() {
  29. throw new AssertionFailedError();
  30. }
  31. };
  32. private static final B uninjectableB = new B() {
  33. @Override void doNothing() {
  34. throw new AssertionFailedError();
  35. }
  36. };
  37. private static final C myFavouriteC = new C();
  38. public void testMembersInjectorFromBinder() {
  39. final AtomicReference<MembersInjector<A<C>>> aMembersInjectorReference
  40. = new AtomicReference<MembersInjector<A<C>>>();
  41. final AtomicReference<MembersInjector<B>> bMembersInjectorReference
  42. = new AtomicReference<MembersInjector<B>>();
  43. Guice.createInjector(new AbstractModule() {
  44. @Override protected void configure() {
  45. MembersInjector<A<C>> aMembersInjector = getMembersInjector(new TypeLiteral<A<C>>() {});
  46. try {
  47. aMembersInjector.injectMembers(uninjectableA);
  48. fail();
  49. } catch (IllegalStateException expected) {
  50. assertContains(expected.getMessage(),
  51. "This MembersInjector cannot be used until the Injector has been created.");
  52. }
  53. MembersInjector<B> bMembersInjector = getMembersInjector(B.class);
  54. try {
  55. bMembersInjector.injectMembers(uninjectableB);
  56. fail();
  57. } catch (IllegalStateException expected) {
  58. assertContains(expected.getMessage(),
  59. "This MembersInjector cannot be used until the Injector has been created.");
  60. }
  61. aMembersInjectorReference.set(aMembersInjector);
  62. bMembersInjectorReference.set(bMembersInjector);
  63. assertEquals("MembersInjector<java.lang.String>",
  64. getMembersInjector(String.class).toString());
  65. bind(C.class).toInstance(myFavouriteC);
  66. }
  67. });
  68. A<C> injectableA = new A<C>();
  69. aMembersInjectorReference.get().injectMembers(injectableA);
  70. assertSame(myFavouriteC, injectableA.t);
  71. assertSame(myFavouriteC, injectableA.b.c);
  72. B injectableB = new B();
  73. bMembersInjectorReference.get().injectMembers(injectableB);
  74. assertSame(myFavouriteC, injectableB.c);
  75. B anotherInjectableB = new B();
  76. bMembersInjectorReference.get().injectMembers(anotherInjectableB);
  77. assertSame(myFavouriteC, anotherInjectableB.c);
  78. }
  79. public void testMembersInjectorFromInjector() {
  80. Injector injector = Guice.createInjector(new AbstractModule() {
  81. protected void configure() {
  82. bind(C.class).toInstance(myFavouriteC);
  83. }
  84. });
  85. MembersInjector<A<C>> aMembersInjector
  86. = injector.getMembersInjector(new TypeLiteral<A<C>>() {});
  87. MembersInjector<B> bMembersInjector = injector.getMembersInjector(B.class);
  88. A<C> injectableA = new A<C>();
  89. aMembersInjector.injectMembers(injectableA);
  90. assertSame(myFavouriteC, injectableA.t);
  91. assertSame(myFavouriteC, injectableA.b.c);
  92. B injectableB = new B();
  93. bMembersInjector.injectMembers(injectableB);
  94. assertSame(myFavouriteC, injectableB.c);
  95. B anotherInjectableB = new B();
  96. bMembersInjector.injectMembers(anotherInjectableB);
  97. assertSame(myFavouriteC, anotherInjectableB.c);
  98. assertEquals("MembersInjector<java.lang.String>",
  99. injector.getMembersInjector(String.class).toString());
  100. }
  101. public void testMembersInjectorWithNonInjectedTypes() {
  102. Injector injector = Guice.createInjector();
  103. MembersInjector<NoInjectedMembers> membersInjector
  104. = injector.getMembersInjector(NoInjectedMembers.class);
  105. membersInjector.injectMembers(new NoInjectedMembers());
  106. membersInjector.injectMembers(new NoInjectedMembers());
  107. }
  108. public void testInjectionFailure() {
  109. Injector injector = Guice.createInjector();
  110. MembersInjector<InjectionFailure> membersInjector
  111. = injector.getMembersInjector(InjectionFailure.class);
  112. try {
  113. membersInjector.injectMembers(new InjectionFailure());
  114. fail();
  115. } catch (ProvisionException expected) {
  116. assertContains(expected.getMessage(),
  117. "1) Error injecting method, java.lang.ClassCastException: whoops, failure #1");
  118. }
  119. }
  120. public void testInjectionAppliesToSpecifiedType() {
  121. Injector injector = Guice.createInjector();
  122. MembersInjector<Object> membersInjector = injector.getMembersInjector(Object.class);
  123. membersInjector.injectMembers(new InjectionFailure());
  124. }
  125. public void testInjectingMembersInjector() {
  126. InjectsMembersInjector injectsMembersInjector = Guice.createInjector(new AbstractModule() {
  127. protected void configure() {
  128. bind(C.class).toInstance(myFavouriteC);
  129. }
  130. }).getInstance(InjectsMembersInjector.class);
  131. A<C> a = new A<C>();
  132. injectsMembersInjector.aMembersInjector.injectMembers(a);
  133. assertSame(myFavouriteC, a.t);
  134. assertSame(myFavouriteC, a.b.c);
  135. }
  136. public void testCannotBindMembersInjector() {
  137. try {
  138. Guice.createInjector(new AbstractModule() {
  139. protected void configure() {
  140. bind(MembersInjector.class).toProvider(Providers.<MembersInjector>of(null));
  141. }
  142. });
  143. fail();
  144. } catch (CreationException expected) {
  145. assertContains(expected.getMessage(),
  146. "1) Binding to core guice framework type is not allowed: MembersInjector.");
  147. }
  148. try {
  149. Guice.createInjector(new AbstractModule() {
  150. protected void configure() {
  151. bind(new TypeLiteral<MembersInjector<A<C>>>() {})
  152. .toProvider(Providers.<MembersInjector<A<C>>>of(null));
  153. }
  154. });
  155. fail();
  156. } catch (CreationException expected) {
  157. assertContains(expected.getMessage(),
  158. "1) Binding to core guice framework type is not allowed: MembersInjector.");
  159. }
  160. }
  161. public void testInjectingMembersInjectorWithErrorsInDependencies() {
  162. try {
  163. Guice.createInjector().getInstance(InjectsBrokenMembersInjector.class);
  164. fail();
  165. } catch (ConfigurationException expected) {
  166. assertContains(expected.getMessage(),
  167. "1) No implementation for " + Unimplemented.class.getName() + " was bound.",
  168. "while locating " + Unimplemented.class.getName(),
  169. "for field at " + A.class.getName() + ".t(MembersInjectorTest.java:",
  170. "while locating com.google.inject.MembersInjector<",
  171. "for field at " + InjectsBrokenMembersInjector.class.getName() + ".aMembersInjector(",
  172. "while locating " + InjectsBrokenMembersInjector.class.getName());
  173. }
  174. }
  175. public void testLookupMembersInjectorBinding() {
  176. Injector injector = Guice.createInjector(new AbstractModule() {
  177. protected void configure() {
  178. bind(C.class).toInstance(myFavouriteC);
  179. }
  180. });
  181. MembersInjector<A<C>> membersInjector =
  182. injector.getInstance(new Key<MembersInjector<A<C>>>() {});
  183. A<C> a = new A<C>();
  184. membersInjector.injectMembers(a);
  185. assertSame(myFavouriteC, a.t);
  186. assertSame(myFavouriteC, a.b.c);
  187. assertEquals("MembersInjector<java.lang.String>",
  188. injector.getInstance(new Key<MembersInjector<String>>() {}).toString());
  189. }
  190. public void testGettingRawMembersInjector() {
  191. Injector injector = Guice.createInjector();
  192. try {
  193. injector.getInstance(MembersInjector.class);
  194. fail();
  195. } catch (ConfigurationException expected) {
  196. assertContains(expected.getMessage(),
  197. "Cannot inject a MembersInjector that has no type parameter");
  198. }
  199. }
  200. public void testGettingAnnotatedMembersInjector() {
  201. Injector injector = Guice.createInjector();
  202. try {
  203. injector.getInstance(new Key<MembersInjector<String>>(Names.named("foo")) {});
  204. fail();
  205. } catch (ConfigurationException expected) {
  206. assertContains(expected.getMessage(),
  207. "1) No implementation for com.google.inject.MembersInjector<java.lang.String> "
  208. + "annotated with @com.google.inject.name.Named(value=foo) was bound.");
  209. }
  210. }
  211. static class A<T> {
  212. @Inject B b;
  213. @Inject T t;
  214. @Inject void doNothing() {}
  215. }
  216. static class B {
  217. @Inject C c;
  218. @Inject void doNothing() {}
  219. }
  220. static class C {}
  221. static class NoInjectedMembers {}
  222. static class InjectionFailure {
  223. int failures = 0;
  224. @Inject void fail() {
  225. throw new ClassCastException("whoops, failure #" + (++failures));
  226. }
  227. }
  228. static class InjectsMembersInjector {
  229. @Inject MembersInjector<A<C>> aMembersInjector;
  230. @Inject A<B> ab;
  231. }
  232. static class InjectsBrokenMembersInjector {
  233. @Inject MembersInjector<A<Unimplemented>> aMembersInjector;
  234. }
  235. static interface Unimplemented {}
  236. }