Home | History | Annotate | Download | only in inject
      1 /**
      2  * Copyright (C) 2006 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 
     17 package com.google.inject;
     18 
     19 import static com.google.inject.name.Names.named;
     20 
     21 import com.google.inject.name.Named;
     22 
     23 import junit.framework.TestCase;
     24 
     25 import java.util.Arrays;
     26 import java.util.List;
     27 
     28 /**
     29  * @author crazybob (at) google.com (Bob Lee)
     30  */
     31 public class ProviderInjectionTest extends TestCase {
     32 
     33   public void testProviderInjection() throws CreationException {
     34     Injector injector = Guice.createInjector(new AbstractModule() {
     35       protected void configure() {
     36         bind(Bar.class);
     37         bind(SampleSingleton.class).in(Scopes.SINGLETON);
     38       }
     39     });
     40 
     41     Foo foo = injector.getInstance(Foo.class);
     42 
     43     Bar bar = foo.barProvider.get();
     44     assertNotNull(bar);
     45     assertNotSame(bar, foo.barProvider.get());
     46 
     47     SampleSingleton singleton = foo.singletonProvider.get();
     48     assertNotNull(singleton);
     49     assertSame(singleton, foo.singletonProvider.get());
     50   }
     51 
     52   /** Test for bug 155. */
     53   public void testProvidersAreInjectedWhenBound() {
     54     Module m = new AbstractModule() {
     55       @Override
     56       protected void configure() {
     57         bind(Bar.class).toProvider(new Provider<Bar>() {
     58           @SuppressWarnings("unused")
     59           @Inject void cantBeCalled(Baz baz) {
     60             fail("Can't have called this method since Baz is not bound.");
     61           }
     62           public Bar get() {
     63             return new Bar() {};
     64           }
     65         });
     66       }
     67     };
     68 
     69     try {
     70       Guice.createInjector(m);
     71       fail("Should have thrown a CreationException");
     72     }
     73     catch (CreationException expected) {
     74     }
     75   }
     76 
     77   /**
     78    * When custom providers are used at injector creation time, they should be
     79    * injected before use. In this testcase, we verify that a provider for
     80    * List.class is injected before it is used.
     81    */
     82   public void testProvidersAreInjectedBeforeTheyAreUsed() {
     83     Injector injector = Guice.createInjector(new AbstractModule() {
     84       public void configure() {
     85         // should bind String to "[true]"
     86         bind(String.class).toProvider(new Provider<String>() {
     87           private String value;
     88           @Inject void initialize(List list) {
     89             value = list.toString();
     90           }
     91           public String get() {
     92             return value;
     93           }
     94         });
     95 
     96         // should bind List to [true]
     97         bind(List.class).toProvider(new Provider<List>() {
     98           @Inject Boolean injectedYet = Boolean.FALSE;
     99           public List get() {
    100             return Arrays.asList(injectedYet);
    101           }
    102         });
    103 
    104         // should bind Boolean to true
    105         bind(Boolean.class).toInstance(Boolean.TRUE);
    106       }
    107     });
    108 
    109     assertEquals("Providers not injected before use",
    110         "[true]",
    111         injector.getInstance(String.class));
    112   }
    113 
    114   /**
    115    * This test ensures that regardless of binding order, instances are injected
    116    * before they are used. It injects mutable Count objects and records their
    117    * value at the time that they're injected.
    118    */
    119   public void testCreationTimeInjectionOrdering() {
    120     Injector injector = Guice.createInjector(new AbstractModule() {
    121       protected void configure() {
    122         // instance injection
    123         bind(Count.class).annotatedWith(named("a")).toInstance(new Count(0) {
    124           @Inject void initialize(@Named("b") Count bCount) {
    125             value = bCount.value + 1;
    126           }
    127         });
    128 
    129         // provider injection
    130         bind(Count.class).annotatedWith(named("b")).toProvider(new Provider<Count>() {
    131           Count count;
    132           @Inject void initialize(@Named("c") Count cCount) {
    133             count = new Count(cCount.value + 2);
    134           }
    135           public Count get() {
    136             return count;
    137           }
    138         });
    139 
    140         // field and method injection, fields first
    141         bind(Count.class).annotatedWith(named("c")).toInstance(new Count(0) {
    142           @Inject @Named("d") Count dCount;
    143           @Inject void initialize(@Named("e") Count eCount) {
    144             value = dCount.value + eCount.value + 4;
    145           }
    146         });
    147 
    148         // static injection
    149         requestStaticInjection(StaticallyInjectable.class);
    150 
    151         bind(Count.class).annotatedWith(named("d")).toInstance(new Count(8));
    152         bind(Count.class).annotatedWith(named("e")).toInstance(new Count(16));
    153       }
    154     });
    155 
    156     assertEquals(28, injector.getInstance(Key.get(Count.class, named("c"))).value);
    157     assertEquals(30, injector.getInstance(Key.get(Count.class, named("b"))).value);
    158     assertEquals(31, injector.getInstance(Key.get(Count.class, named("a"))).value);
    159     assertEquals(28, StaticallyInjectable.cCountAtInjectionTime);
    160   }
    161 
    162   static class Count {
    163     int value;
    164     Count(int value) {
    165       this.value = value;
    166     }
    167   }
    168 
    169   static class StaticallyInjectable {
    170     static int cCountAtInjectionTime;
    171     @Inject static void initialize(@Named("c") Count cCount) {
    172       cCountAtInjectionTime = cCount.value;
    173     }
    174   }
    175 
    176   static class Foo {
    177     @Inject Provider<Bar> barProvider;
    178     @Inject Provider<SampleSingleton> singletonProvider;
    179   }
    180 
    181   static class Bar {}
    182 
    183   static class SampleSingleton {}
    184 
    185   interface Baz { }
    186 
    187 }
    188