| /** |
| * Copyright (C) 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| package com.google.inject; |
| |
| import static com.google.inject.Asserts.assertContains; |
| import com.google.inject.name.Named; |
| import com.google.inject.name.Names; |
| import junit.framework.TestCase; |
| |
| /** |
| * This test verifies the ways things are injected (ie. getInstance(), |
| * injectMembers(), bind to instance, and bind to provider instance) for all |
| * states of optional bindings (fields, methods, multiple-argument methods, |
| * provider fields, provider methods, constructors). |
| * |
| * @author [email protected] (Jesse Wilson) |
| */ |
| public class OptionalBindingTest extends TestCase { |
| |
| private static final A injectA = new A() {}; |
| private static final B injectB = new B() {}; |
| private static final C injectC = new C() {}; |
| private static final D injectD = new D() {}; |
| private static final E injectE = new E() {}; |
| private static final F injectF = new F() {}; |
| private static final G injectG = new G() {}; |
| |
| private Module everythingModule = new AbstractModule() { |
| protected void configure() { |
| bind(A.class).toInstance(injectA); |
| bind(B.class).toInstance(injectB); |
| bind(C.class).toInstance(injectC); |
| bind(D.class).toInstance(injectD); |
| bind(E.class).annotatedWith(Names.named("e")).toInstance(injectE); |
| bind(F.class).toInstance(injectF); |
| bind(G.class).toInstance(injectG); |
| } |
| }; |
| |
| private Module partialModule = new AbstractModule() { |
| protected void configure() { |
| bind(C.class).toInstance(new C() {}); |
| } |
| }; |
| |
| private Module toInstanceModule = new AbstractModule() { |
| protected void configure() { |
| bind(HasOptionalInjections.class) |
| .toInstance(new HasOptionalInjections()); |
| } |
| }; |
| |
| private Module toProviderInstanceModule = new AbstractModule() { |
| protected void configure() { |
| bind(HasOptionalInjections.class) |
| .toProvider(new HasOptionalInjectionsProvider()); |
| } |
| }; |
| |
| private Module toProviderModule = new AbstractModule() { |
| protected void configure() { |
| bind(HasOptionalInjections.class) |
| .toProvider(HasOptionalInjectionsProvider.class); |
| } |
| }; |
| |
| public void testEverythingInjectorGetInstance() { |
| Guice.createInjector(everythingModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertEverythingInjected(); |
| } |
| |
| public void testPartialInjectorGetInstance() { |
| Guice.createInjector(partialModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testNothingInjectorGetInstance() { |
| Guice.createInjector() |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testEverythingInjectorInjectMembers() { |
| HasOptionalInjections instance = new HasOptionalInjections(); |
| Guice.createInjector(everythingModule).injectMembers(instance); |
| instance.assertEverythingInjected(); |
| } |
| |
| public void testPartialInjectorInjectMembers() { |
| HasOptionalInjections instance = new HasOptionalInjections(); |
| Guice.createInjector(partialModule).injectMembers(instance); |
| instance.assertNothingInjected(); |
| } |
| |
| public void testNothingInjectorInjectMembers() { |
| HasOptionalInjections instance = new HasOptionalInjections(); |
| Guice.createInjector().injectMembers(instance); |
| instance.assertNothingInjected(); |
| } |
| |
| public void testEverythingInjectorToInstance() { |
| Guice.createInjector(everythingModule, toInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertEverythingInjected(); |
| } |
| |
| public void testPartialInjectorToInstance() { |
| Guice.createInjector(partialModule, toInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testNothingInjectorToInstance() { |
| Guice.createInjector(toInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testEverythingInjectorToProviderInstance() { |
| Guice.createInjector(everythingModule, toProviderInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertEverythingInjected(); |
| } |
| |
| public void testPartialInjectorToProviderInstance() { |
| Guice.createInjector(partialModule, toProviderInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testNothingInjectorToProviderInstance() { |
| Guice.createInjector(toProviderInstanceModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testEverythingInjectorToProvider() { |
| Guice.createInjector(everythingModule, toProviderModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertEverythingInjected(); |
| } |
| |
| public void testPartialInjectorToProvider() { |
| Guice.createInjector(partialModule, toProviderModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| public void testNothingInjectorToProvider() { |
| Guice.createInjector(toProviderModule) |
| .getInstance(HasOptionalInjections.class) |
| .assertNothingInjected(); |
| } |
| |
| static class HasOptionalInjections { |
| A originalA = new A() {}; |
| @Inject(optional=true) A a = originalA; // field injection |
| B b; // method injection with one argument |
| C c; // method injection with two arguments |
| D d; // method injection with two arguments |
| E e; // annotated injection |
| @Inject(optional=true) Provider<F> fProvider; // provider |
| Provider<G> gProvider; // method injection of provider |
| boolean invoked0, invoked1, invoked2, invokedAnnotated, invokeProvider; |
| |
| @Inject(optional=true) void methodInjectZeroArguments() { |
| invoked0 = true; |
| } |
| |
| @Inject(optional=true) void methodInjectOneArgument(B b) { |
| this.b = b; |
| invoked1 = true; |
| } |
| |
| @Inject(optional=true) void methodInjectTwoArguments(C c, D d) { |
| this.c = c; |
| this.d = d; |
| invoked2 = true; |
| } |
| |
| @Inject(optional=true) void methodInjectAnnotated(@Named("e") E e) { |
| this.e = e; |
| invokedAnnotated = true; |
| } |
| |
| @Inject(optional=true) void methodInjectProvider(Provider<G> gProvider) { |
| this.gProvider = gProvider; |
| invokeProvider = true; |
| } |
| |
| void assertNothingInjected() { |
| assertSame(originalA, a); |
| assertNull(b); |
| assertNull(c); |
| assertNull(d); |
| assertNull(e); |
| assertNull(fProvider); |
| assertNull(gProvider); |
| assertTrue(invoked0); |
| assertFalse(invoked1); |
| assertFalse(invoked2); |
| assertFalse(invokedAnnotated); |
| } |
| |
| public void assertEverythingInjected() { |
| assertNotSame(injectA, originalA); |
| assertSame(injectA, a); |
| assertSame(injectB, b); |
| assertSame(injectC, c); |
| assertSame(injectD, d); |
| assertSame(injectE, e); |
| assertSame(injectF, fProvider.get()); |
| assertSame(injectG, gProvider.get()); |
| assertTrue(invoked0); |
| assertTrue(invoked1); |
| assertTrue(invoked2); |
| assertTrue(invokedAnnotated); |
| } |
| } |
| |
| static class HasOptionalInjectionsProvider |
| extends HasOptionalInjections implements Provider<HasOptionalInjections> { |
| public HasOptionalInjections get() { |
| return this; |
| } |
| } |
| |
| public void testOptionalConstructorBlowsUp() { |
| try { |
| Guice.createInjector().getInstance(HasOptionalConstructor.class); |
| fail(); |
| } catch (ConfigurationException expected) { |
| assertContains(expected.getMessage(), |
| "@Inject(optional=true) is not allowed on constructors"); |
| } |
| } |
| |
| static class HasOptionalConstructor { |
| @Inject(optional=true) |
| HasOptionalConstructor() {} |
| } |
| |
| @Inject(optional=true) static A staticInjectA; |
| |
| public void testStaticInjection() { |
| staticInjectA = injectA; |
| Guice.createInjector(new AbstractModule() { |
| protected void configure() { |
| requestStaticInjection(OptionalBindingTest.class); |
| } |
| }); |
| assertSame(staticInjectA, injectA); |
| } |
| |
| /** |
| * Test for bug 107, where we weren't doing optional injection properly for |
| * indirect injections. |
| */ |
| public void testIndirectOptionalInjection() { |
| Indirect indirect = Guice.createInjector().getInstance(Indirect.class); |
| assertNotNull(indirect.hasOptionalInjections); |
| indirect.hasOptionalInjections.assertNothingInjected(); |
| } |
| |
| static class Indirect { |
| @Inject HasOptionalInjections hasOptionalInjections; |
| } |
| |
| interface A {} |
| interface B {} |
| interface C {} |
| interface D {} |
| interface E {} |
| interface F {} |
| interface G {} |
| } |