PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://gitlab.com/metamorphiccode/guice
Java | 634 lines | 510 code | 73 blank | 51 comment | 2 complexity | 0e313dfbfa419f3dcbe8a3dd65f6d13b MD5 | raw file
  1. /**
  2. * Copyright (C) 2007 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.asModuleChain;
  18. import static com.google.inject.Asserts.assertContains;
  19. import static com.google.inject.Asserts.assertNotSerializable;
  20. import static com.google.inject.Asserts.getDeclaringSourcePart;
  21. import static com.google.inject.Asserts.isIncludeStackTraceOff;
  22. import com.google.common.collect.Iterables;
  23. import com.google.common.collect.Lists;
  24. import com.google.inject.name.Named;
  25. import com.google.inject.name.Names;
  26. import com.google.inject.spi.Message;
  27. import com.google.inject.util.Providers;
  28. import junit.framework.TestCase;
  29. import java.io.IOException;
  30. import java.util.Comparator;
  31. import java.util.Date;
  32. import java.util.List;
  33. import java.util.concurrent.Callable;
  34. import java.util.logging.Handler;
  35. import java.util.logging.LogRecord;
  36. import java.util.logging.Logger;
  37. /**
  38. * @author crazybob@google.com (Bob Lee)
  39. */
  40. public class BinderTest extends TestCase {
  41. private final Logger loggerToWatch = Logger.getLogger(Guice.class.getName());
  42. private final List<LogRecord> logRecords = Lists.newArrayList();
  43. private final Handler fakeHandler = new Handler() {
  44. @Override
  45. public void publish(LogRecord logRecord) {
  46. logRecords.add(logRecord);
  47. }
  48. @Override
  49. public void flush() {}
  50. @Override
  51. public void close() throws SecurityException {}
  52. };
  53. Provider<Foo> fooProvider;
  54. @Override protected void setUp() throws Exception {
  55. super.setUp();
  56. loggerToWatch.addHandler(fakeHandler);
  57. }
  58. @Override protected void tearDown() throws Exception {
  59. loggerToWatch.removeHandler(fakeHandler);
  60. super.tearDown();
  61. }
  62. public void testProviderFromBinder() {
  63. Guice.createInjector(new Module() {
  64. public void configure(Binder binder) {
  65. fooProvider = binder.getProvider(Foo.class);
  66. try {
  67. fooProvider.get();
  68. } catch (IllegalStateException e) { /* expected */ }
  69. }
  70. });
  71. assertNotNull(fooProvider.get());
  72. }
  73. static class Foo {}
  74. public void testMissingBindings() {
  75. try {
  76. Guice.createInjector(new AbstractModule() {
  77. @Override
  78. public void configure() {
  79. getProvider(Runnable.class);
  80. bind(Comparator.class);
  81. requireBinding(Key.get(new TypeLiteral<Callable<String>>() {}));
  82. bind(Date.class).annotatedWith(Names.named("date"));
  83. }
  84. });
  85. } catch (CreationException e) {
  86. assertEquals(4, e.getErrorMessages().size());
  87. String segment1 = "No implementation for " + Comparator.class.getName() + " was bound.";
  88. String segment2 = "No implementation for java.util.Date annotated with @"
  89. + Named.class.getName() + "(value=date) was bound.";
  90. String segment3 = "No implementation for java.lang.Runnable was bound.";
  91. String segment4 = " No implementation for java.util.concurrent.Callable<java.lang.String> was"
  92. + " bound.";
  93. String atSegment = "at " + getClass().getName();
  94. String sourceFileName = getDeclaringSourcePart(getClass());
  95. if (isIncludeStackTraceOff()) {
  96. assertContains(e.getMessage(),
  97. segment1, atSegment, sourceFileName,
  98. segment2, atSegment, sourceFileName,
  99. segment3, atSegment, sourceFileName,
  100. segment4, atSegment, sourceFileName);
  101. } else {
  102. assertContains(e.getMessage(),
  103. segment3, atSegment, sourceFileName,
  104. segment1, atSegment, sourceFileName,
  105. segment4, atSegment, sourceFileName,
  106. segment2, atSegment, sourceFileName);
  107. }
  108. }
  109. }
  110. public void testMissingDependency() {
  111. try {
  112. Guice.createInjector(new AbstractModule() {
  113. @Override
  114. public void configure() {
  115. bind(NeedsRunnable.class);
  116. }
  117. });
  118. } catch (CreationException e) {
  119. assertEquals(1, e.getErrorMessages().size());
  120. assertContains(e.getMessage(),
  121. "No implementation for java.lang.Runnable was bound.",
  122. "for field at " + NeedsRunnable.class.getName(), ".runnable(BinderTest.java:",
  123. "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
  124. }
  125. }
  126. static class NeedsRunnable {
  127. @Inject Runnable runnable;
  128. }
  129. public void testDanglingConstantBinding() {
  130. try {
  131. Guice.createInjector(new AbstractModule() {
  132. @Override public void configure() {
  133. bindConstant();
  134. }
  135. });
  136. fail();
  137. } catch (CreationException expected) {
  138. assertContains(expected.getMessage(),
  139. "1) Missing constant value. Please call to(...).",
  140. "at " + getClass().getName());
  141. }
  142. }
  143. public void testRecursiveBinding() {
  144. try {
  145. Guice.createInjector(new AbstractModule() {
  146. @Override public void configure() {
  147. bind(Runnable.class).to(Runnable.class);
  148. }
  149. });
  150. fail();
  151. } catch (CreationException expected) {
  152. assertContains(expected.getMessage(),
  153. "1) Binding points to itself.",
  154. "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
  155. }
  156. }
  157. public void testBindingNullConstant() {
  158. try {
  159. Guice.createInjector(new AbstractModule() {
  160. @Override public void configure() {
  161. String none = null;
  162. bindConstant().annotatedWith(Names.named("nullOne")).to(none);
  163. bind(String.class).annotatedWith(Names.named("nullTwo")).toInstance(none);
  164. }
  165. });
  166. fail();
  167. } catch (CreationException expected) {
  168. assertContains(expected.getMessage(),
  169. "1) Binding to null instances is not allowed. Use toProvider(Providers.of(null))",
  170. "2) Binding to null instances is not allowed. Use toProvider(Providers.of(null))");
  171. }
  172. }
  173. public void testToStringOnBinderApi() {
  174. try {
  175. Guice.createInjector(new AbstractModule() {
  176. @Override public void configure() {
  177. assertEquals("Binder", binder().toString());
  178. assertEquals("Provider<java.lang.Integer>", getProvider(Integer.class).toString());
  179. assertEquals("Provider<java.util.List<java.lang.String>>",
  180. getProvider(Key.get(new TypeLiteral<List<String>>() {})).toString());
  181. assertEquals("BindingBuilder<java.lang.Integer>",
  182. bind(Integer.class).toString());
  183. assertEquals("BindingBuilder<java.lang.Integer>",
  184. bind(Integer.class).annotatedWith(Names.named("a")).toString());
  185. assertEquals("ConstantBindingBuilder", bindConstant().toString());
  186. assertEquals("ConstantBindingBuilder",
  187. bindConstant().annotatedWith(Names.named("b")).toString());
  188. assertEquals("AnnotatedElementBuilder",
  189. binder().newPrivateBinder().expose(Integer.class).toString());
  190. }
  191. });
  192. fail();
  193. } catch (CreationException ignored) {
  194. }
  195. }
  196. public void testNothingIsSerializableInBinderApi() {
  197. try {
  198. Guice.createInjector(new AbstractModule() {
  199. @Override public void configure() {
  200. try {
  201. assertNotSerializable(binder());
  202. assertNotSerializable(getProvider(Integer.class));
  203. assertNotSerializable(getProvider(Key.get(new TypeLiteral<List<String>>() {})));
  204. assertNotSerializable(bind(Integer.class));
  205. assertNotSerializable(bind(Integer.class).annotatedWith(Names.named("a")));
  206. assertNotSerializable(bindConstant());
  207. assertNotSerializable(bindConstant().annotatedWith(Names.named("b")));
  208. } catch (IOException e) {
  209. fail(e.getMessage());
  210. }
  211. }
  212. });
  213. fail();
  214. } catch (CreationException ignored) {
  215. }
  216. }
  217. /**
  218. * Although {@code String[].class} isn't equal to {@code new
  219. * GenericArrayTypeImpl(String.class)}, Guice should treat these two types
  220. * interchangeably.
  221. */
  222. public void testArrayTypeCanonicalization() {
  223. final String[] strings = new String[] { "A" };
  224. final Integer[] integers = new Integer[] { 1 };
  225. Injector injector = Guice.createInjector(new AbstractModule() {
  226. @Override
  227. protected void configure() {
  228. bind(String[].class).toInstance(strings);
  229. bind(new TypeLiteral<Integer[]>() {}).toInstance(integers);
  230. }
  231. });
  232. assertSame(integers, injector.getInstance(Key.get(new TypeLiteral<Integer[]>() {})));
  233. assertSame(integers, injector.getInstance(new Key<Integer[]>() {}));
  234. assertSame(integers, injector.getInstance(Integer[].class));
  235. assertSame(strings, injector.getInstance(Key.get(new TypeLiteral<String[]>() {})));
  236. assertSame(strings, injector.getInstance(new Key<String[]>() {}));
  237. assertSame(strings, injector.getInstance(String[].class));
  238. try {
  239. Guice.createInjector(new AbstractModule() {
  240. @Override
  241. protected void configure() {
  242. bind(String[].class).toInstance(new String[] { "A" });
  243. bind(new TypeLiteral<String[]>() {}).toInstance(new String[] { "B" });
  244. }
  245. });
  246. fail();
  247. } catch (CreationException expected) {
  248. assertContains(expected.getMessage(),
  249. "1) A binding to java.lang.String[] was already configured at " + getClass().getName(),
  250. "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
  251. assertContains(expected.getMessage(), "1 error");
  252. }
  253. // passes because duplicates are ignored
  254. injector = Guice.createInjector(new AbstractModule() {
  255. @Override
  256. protected void configure() {
  257. bind(String[].class).toInstance(strings);
  258. bind(new TypeLiteral<String[]>() {}).toInstance(strings);
  259. }
  260. });
  261. assertSame(strings, injector.getInstance(Key.get(new TypeLiteral<String[]>() {})));
  262. assertSame(strings, injector.getInstance(new Key<String[]>() {}));
  263. assertSame(strings, injector.getInstance(String[].class));
  264. }
  265. static class ParentModule extends AbstractModule {
  266. @Override protected void configure() {
  267. install(new FooModule());
  268. install(new BarModule());
  269. }
  270. }
  271. static class FooModule extends AbstractModule {
  272. @Override protected void configure() {
  273. install(new ConstantModule("foo"));
  274. }
  275. }
  276. static class BarModule extends AbstractModule {
  277. @Override protected void configure() {
  278. install(new ConstantModule("bar"));
  279. }
  280. }
  281. static class ConstantModule extends AbstractModule {
  282. private final String constant;
  283. ConstantModule(String constant) {
  284. this.constant = constant;
  285. }
  286. @Override protected void configure() {
  287. bind(String.class).toInstance(constant);
  288. }
  289. }
  290. /**
  291. * Binding something to two different things should give an error.
  292. */
  293. public void testSettingBindingTwice() {
  294. try {
  295. Guice.createInjector(new ParentModule());
  296. fail();
  297. } catch(CreationException expected) {
  298. assertContains(expected.getMessage(),
  299. "1) A binding to java.lang.String was already configured at " + ConstantModule.class.getName(),
  300. asModuleChain(ParentModule.class, FooModule.class, ConstantModule.class),
  301. "at " + ConstantModule.class.getName(), getDeclaringSourcePart(getClass()),
  302. asModuleChain(ParentModule.class, BarModule.class, ConstantModule.class));
  303. assertContains(expected.getMessage(), "1 error");
  304. }
  305. }
  306. /**
  307. * Binding an @ImplementedBy thing to something else should also fail.
  308. */
  309. public void testSettingAtImplementedByTwice() {
  310. try {
  311. Guice.createInjector(new AbstractModule() {
  312. @Override
  313. protected void configure() {
  314. bind(HasImplementedBy1.class);
  315. bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
  316. }
  317. });
  318. fail();
  319. } catch(CreationException expected) {
  320. expected.printStackTrace();
  321. assertContains(expected.getMessage(),
  322. "1) A binding to " + HasImplementedBy1.class.getName()
  323. + " was already configured at " + getClass().getName(),
  324. "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
  325. assertContains(expected.getMessage(), "1 error");
  326. }
  327. }
  328. /**
  329. * See issue 614, Problem One
  330. * https://github.com/google/guice/issues/614
  331. */
  332. public void testJitDependencyDoesntBlockOtherExplicitBindings() {
  333. Injector injector = Guice.createInjector(new AbstractModule() {
  334. @Override
  335. protected void configure() {
  336. bind(HasImplementedByThatNeedsAnotherImplementedBy.class);
  337. bind(HasImplementedBy1.class).toInstance(new HasImplementedBy1() {});
  338. }
  339. });
  340. injector.getAllBindings(); // just validate it doesn't throw.
  341. // Also validate that we're using the explicit (and not @ImplementedBy) implementation
  342. assertFalse(injector.getInstance(HasImplementedBy1.class) instanceof ImplementsHasImplementedBy1);
  343. }
  344. /**
  345. * See issue 614, Problem Two
  346. * https://github.com/google/guice/issues/id=614
  347. */
  348. public void testJitDependencyCanUseExplicitDependencies() {
  349. Guice.createInjector(new AbstractModule() {
  350. @Override
  351. protected void configure() {
  352. bind(HasImplementedByThatWantsExplicit.class);
  353. bind(JustAnInterface.class).toInstance(new JustAnInterface() {});
  354. }
  355. });
  356. }
  357. /**
  358. * Untargetted bindings should follow @ImplementedBy and @ProvidedBy
  359. * annotations if they exist. Otherwise the class should be constructed
  360. * directly.
  361. */
  362. public void testUntargettedBinding() {
  363. Injector injector = Guice.createInjector(new AbstractModule() {
  364. @Override
  365. protected void configure() {
  366. bind(HasProvidedBy1.class);
  367. bind(HasImplementedBy1.class);
  368. bind(HasProvidedBy2.class);
  369. bind(HasImplementedBy2.class);
  370. bind(JustAClass.class);
  371. }
  372. });
  373. assertNotNull(injector.getInstance(HasProvidedBy1.class));
  374. assertNotNull(injector.getInstance(HasImplementedBy1.class));
  375. assertNotSame(HasProvidedBy2.class,
  376. injector.getInstance(HasProvidedBy2.class).getClass());
  377. assertSame(ExtendsHasImplementedBy2.class,
  378. injector.getInstance(HasImplementedBy2.class).getClass());
  379. assertSame(JustAClass.class, injector.getInstance(JustAClass.class).getClass());
  380. }
  381. public void testPartialInjectorGetInstance() {
  382. Injector injector = Guice.createInjector();
  383. try {
  384. injector.getInstance(MissingParameter.class);
  385. fail();
  386. } catch (ConfigurationException expected) {
  387. assertContains(expected.getMessage(),
  388. "1) Could not find a suitable constructor in " + NoInjectConstructor.class.getName(),
  389. "at " + MissingParameter.class.getName() + ".<init>(BinderTest.java:");
  390. }
  391. }
  392. public void testUserReportedError() {
  393. final Message message = new Message(getClass(), "Whoops!");
  394. try {
  395. Guice.createInjector(new AbstractModule() {
  396. @Override
  397. protected void configure() {
  398. addError(message);
  399. }
  400. });
  401. fail();
  402. } catch (CreationException expected) {
  403. assertSame(message, Iterables.getOnlyElement(expected.getErrorMessages()));
  404. }
  405. }
  406. public void testUserReportedErrorsAreAlsoLogged() {
  407. try {
  408. Guice.createInjector(new AbstractModule() {
  409. @Override
  410. protected void configure() {
  411. addError(new Message("Whoops!", new IllegalArgumentException()));
  412. }
  413. });
  414. fail();
  415. } catch (CreationException expected) {
  416. }
  417. LogRecord logRecord = Iterables.getOnlyElement(this.logRecords);
  418. assertContains(logRecord.getMessage(),
  419. "An exception was caught and reported. Message: java.lang.IllegalArgumentException");
  420. }
  421. public void testBindingToProvider() {
  422. try {
  423. Guice.createInjector(new AbstractModule() {
  424. @Override
  425. protected void configure() {
  426. bind(new TypeLiteral<Provider<String>>() {}).toInstance(Providers.of("A"));
  427. }
  428. });
  429. fail();
  430. } catch (CreationException expected) {
  431. assertContains(expected.getMessage(),
  432. "1) Binding to Provider is not allowed.",
  433. "at " + BinderTest.class.getName(), getDeclaringSourcePart(getClass()));
  434. }
  435. }
  436. static class OuterCoreModule extends AbstractModule {
  437. @Override protected void configure() {
  438. install(new InnerCoreModule());
  439. }
  440. }
  441. static class InnerCoreModule extends AbstractModule {
  442. final Named red = Names.named("red");
  443. @Override protected void configure() {
  444. bind(AbstractModule.class).annotatedWith(red)
  445. .toProvider(Providers.<AbstractModule>of(null));
  446. bind(Binder.class).annotatedWith(red).toProvider(Providers.<Binder>of(null));
  447. bind(Binding.class).annotatedWith(red).toProvider(Providers.<Binding>of(null));
  448. bind(Injector.class).annotatedWith(red).toProvider(Providers.<Injector>of(null));
  449. bind(Key.class).annotatedWith(red).toProvider(Providers.<Key>of(null));
  450. bind(Module.class).annotatedWith(red).toProvider(Providers.<Module>of(null));
  451. bind(Provider.class).annotatedWith(red).toProvider(Providers.<Provider>of(null));
  452. bind(Scope.class).annotatedWith(red).toProvider(Providers.<Scope>of(null));
  453. bind(Stage.class).annotatedWith(red).toProvider(Providers.<Stage>of(null));
  454. bind(TypeLiteral.class).annotatedWith(red).toProvider(Providers.<TypeLiteral>of(null));
  455. bind(new TypeLiteral<Key<String>>() {}).toProvider(Providers.<Key<String>>of(null));
  456. }
  457. }
  458. public void testCannotBindToGuiceTypes() {
  459. try {
  460. Guice.createInjector(new OuterCoreModule());
  461. fail();
  462. } catch (CreationException expected) {
  463. assertContains(expected.getMessage(),
  464. "Binding to core guice framework type is not allowed: AbstractModule.",
  465. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  466. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  467. "Binding to core guice framework type is not allowed: Binder.",
  468. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  469. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  470. "Binding to core guice framework type is not allowed: Binding.",
  471. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  472. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  473. "Binding to core guice framework type is not allowed: Injector.",
  474. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  475. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  476. "Binding to core guice framework type is not allowed: Key.",
  477. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  478. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  479. "Binding to core guice framework type is not allowed: Module.",
  480. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  481. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  482. "Binding to Provider is not allowed.",
  483. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  484. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  485. "Binding to core guice framework type is not allowed: Scope.",
  486. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  487. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  488. "Binding to core guice framework type is not allowed: Stage.",
  489. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  490. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  491. "Binding to core guice framework type is not allowed: TypeLiteral.",
  492. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  493. asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
  494. "Binding to core guice framework type is not allowed: Key.",
  495. "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
  496. asModuleChain(OuterCoreModule.class, InnerCoreModule.class));
  497. }
  498. }
  499. static class MissingParameter {
  500. @Inject MissingParameter(NoInjectConstructor noInjectConstructor) {}
  501. }
  502. static class NoInjectConstructor {
  503. private NoInjectConstructor() {}
  504. }
  505. @ProvidedBy(HasProvidedBy1Provider.class)
  506. interface HasProvidedBy1 {}
  507. static class HasProvidedBy1Provider implements Provider<HasProvidedBy1> {
  508. public HasProvidedBy1 get() {
  509. return new HasProvidedBy1() {};
  510. }
  511. }
  512. @ImplementedBy(ImplementsHasImplementedBy1.class)
  513. interface HasImplementedBy1 {}
  514. static class ImplementsHasImplementedBy1 implements HasImplementedBy1 {}
  515. @ProvidedBy(HasProvidedBy2Provider.class)
  516. static class HasProvidedBy2 {}
  517. static class HasProvidedBy2Provider implements Provider<HasProvidedBy2> {
  518. public HasProvidedBy2 get() {
  519. return new HasProvidedBy2() {};
  520. }
  521. }
  522. @ImplementedBy(ExtendsHasImplementedBy2.class)
  523. static class HasImplementedBy2 {}
  524. static class ExtendsHasImplementedBy2 extends HasImplementedBy2 {}
  525. static class JustAClass {}
  526. @ImplementedBy(ImplementsHasImplementedByThatNeedsAnotherImplementedBy.class)
  527. static interface HasImplementedByThatNeedsAnotherImplementedBy {
  528. }
  529. static class ImplementsHasImplementedByThatNeedsAnotherImplementedBy
  530. implements HasImplementedByThatNeedsAnotherImplementedBy {
  531. @Inject
  532. ImplementsHasImplementedByThatNeedsAnotherImplementedBy(
  533. HasImplementedBy1 h1n1) {}
  534. }
  535. @ImplementedBy(ImplementsHasImplementedByThatWantsExplicit.class)
  536. static interface HasImplementedByThatWantsExplicit {
  537. }
  538. static class ImplementsHasImplementedByThatWantsExplicit
  539. implements HasImplementedByThatWantsExplicit {
  540. @Inject ImplementsHasImplementedByThatWantsExplicit(JustAnInterface jai) {}
  541. }
  542. static interface JustAnInterface {}
  543. // public void testBindInterfaceWithoutImplementation() {
  544. // Guice.createInjector(new AbstractModule() {
  545. // protected void configure() {
  546. // bind(Runnable.class);
  547. // }
  548. // }).getInstance(Runnable.class);
  549. // }
  550. enum Roshambo { ROCK, SCISSORS, PAPER }
  551. public void testInjectRawProvider() {
  552. try {
  553. Guice.createInjector().getInstance(Provider.class);
  554. fail();
  555. } catch (ConfigurationException expected) {
  556. Asserts.assertContains(expected.getMessage(),
  557. "1) Cannot inject a Provider that has no type parameter",
  558. "while locating " + Provider.class.getName());
  559. }
  560. }
  561. }