Home | History | Annotate | Download | only in fieldbinder
      1 /*
      2  * Copyright (C) 2014 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.testing.fieldbinder;
     18 
     19 import static com.google.inject.Asserts.assertContains;
     20 import static java.lang.annotation.RetentionPolicy.RUNTIME;
     21 
     22 import com.google.inject.BindingAnnotation;
     23 import com.google.inject.ConfigurationException;
     24 import com.google.inject.CreationException;
     25 import com.google.inject.Guice;
     26 import com.google.inject.Inject;
     27 import com.google.inject.Injector;
     28 import com.google.inject.Key;
     29 import com.google.inject.Provider;
     30 import com.google.inject.ProvisionException;
     31 import com.google.inject.name.Named;
     32 import com.google.inject.name.Names;
     33 import com.google.inject.util.Providers;
     34 
     35 import junit.framework.TestCase;
     36 
     37 import java.lang.annotation.Retention;
     38 import java.util.Arrays;
     39 import java.util.List;
     40 
     41 import javax.inject.Qualifier;
     42 
     43 /** Unit tests for {@link BoundFieldModule}. */
     44 public class BoundFieldModuleTest extends TestCase {
     45   public void testBindingNothing() {
     46     Object instance = new Object() {};
     47 
     48     BoundFieldModule module = BoundFieldModule.of(instance);
     49     Guice.createInjector(module);
     50 
     51     // If we didn't throw an exception, we succeeded.
     52   }
     53 
     54   public void testBindingOnePrivate() {
     55     final Integer testValue = 1024;
     56     Object instance = new Object() {
     57       @Bind private Integer anInt = testValue;
     58     };
     59 
     60     BoundFieldModule module = BoundFieldModule.of(instance);
     61     Injector injector = Guice.createInjector(module);
     62 
     63     assertEquals(testValue, injector.getInstance(Integer.class));
     64   }
     65 
     66   public void testBindingOnePublic() {
     67     final Integer testValue = 1024;
     68     Object instance = new Object() {
     69       @Bind public Integer anInt = testValue;
     70     };
     71 
     72     BoundFieldModule module = BoundFieldModule.of(instance);
     73     Injector injector = Guice.createInjector(module);
     74 
     75     assertEquals(testValue, injector.getInstance(Integer.class));
     76   }
     77 
     78   private static class FieldBindableClass {
     79     @Bind Integer anInt;
     80 
     81     FieldBindableClass(Integer anInt) {
     82       this.anInt = anInt;
     83     }
     84   }
     85 
     86   private static class FieldBindableSubclass extends FieldBindableClass {
     87     FieldBindableSubclass(Integer anInt) {
     88       super(anInt);
     89     }
     90   }
     91 
     92   public void testSuperTypeBinding() {
     93     FieldBindableSubclass instance = new FieldBindableSubclass(1024);
     94 
     95     BoundFieldModule module = BoundFieldModule.of(instance);
     96     Injector injector = Guice.createInjector(module);
     97 
     98     assertEquals(instance.anInt, injector.getInstance(Integer.class));
     99   }
    100 
    101   public void testBindingTwo() {
    102     final Integer testValue = 1024;
    103     final String testString = "Hello World!";
    104     Object instance = new Object() {
    105       @Bind private Integer anInt = testValue;
    106       @Bind private String aString = testString;
    107     };
    108 
    109     BoundFieldModule module = BoundFieldModule.of(instance);
    110     Injector injector = Guice.createInjector(module);
    111 
    112     assertEquals(testValue, injector.getInstance(Integer.class));
    113     assertEquals(testString, injector.getInstance(String.class));
    114   }
    115 
    116   public void testBindingSuperType() {
    117     final Integer testValue = 1024;
    118     Object instance = new Object() {
    119       @Bind(to = Number.class) private Integer anInt = testValue;
    120     };
    121 
    122     BoundFieldModule module = BoundFieldModule.of(instance);
    123     Injector injector = Guice.createInjector(module);
    124 
    125     assertEquals(testValue, injector.getInstance(Number.class));
    126   }
    127 
    128   public void testBindingSuperTypeAccessSubType() {
    129     final Integer testValue = 1024;
    130     Object instance = new Object() {
    131       @Bind(to = Number.class) private Integer anInt = testValue;
    132     };
    133 
    134     BoundFieldModule module = BoundFieldModule.of(instance);
    135     Injector injector = Guice.createInjector(module);
    136 
    137     try {
    138       injector.getInstance(Integer.class);
    139     } catch (ConfigurationException e) {
    140       assertContains(
    141           e.getMessage(),
    142           "Could not find a suitable constructor in java.lang.Integer");
    143     }
    144   }
    145 
    146   public void testBindingIncorrectTypeProviderFails() {
    147     final Integer testValue = 1024;
    148     Object instance = new Object() {
    149       @Bind(to = String.class) private Provider<Integer> anIntProvider = new Provider<Integer>() {
    150         @Override public Integer get() {
    151           return testValue;
    152         }
    153       };
    154     };
    155 
    156     BoundFieldModule module = BoundFieldModule.of(instance);
    157 
    158     try {
    159       Guice.createInjector(module);
    160       fail();
    161     } catch (CreationException e) {
    162       assertContains(
    163           e.getMessage(),
    164           "Requested binding type \"java.lang.String\" is not "
    165           + "assignable from field binding type \"java.lang.Integer\"");
    166     }
    167   }
    168 
    169   @BindingAnnotation
    170   @Retention(RUNTIME)
    171   private static @interface SomeBindingAnnotation {}
    172 
    173   public void testBindingWithBindingAnnotation() {
    174     final Integer testValue1 = 1024, testValue2 = 2048;
    175     Object instance = new Object() {
    176       @Bind private Integer anInt = testValue1;
    177 
    178       @Bind
    179       @SomeBindingAnnotation
    180       private Integer anotherInt = testValue2;
    181     };
    182 
    183     BoundFieldModule module = BoundFieldModule.of(instance);
    184     Injector injector = Guice.createInjector(module);
    185 
    186     assertEquals(testValue1, injector.getInstance(Integer.class));
    187     assertEquals(
    188         testValue2,
    189         injector.getInstance(Key.get(Integer.class, SomeBindingAnnotation.class)));
    190   }
    191 
    192   @Qualifier
    193   @Retention(RUNTIME)
    194   private static @interface SomeQualifier {}
    195 
    196   public void testBindingWithQualifier() {
    197     final Integer testValue1 = 1024, testValue2 = 2048;
    198     Object instance = new Object() {
    199       @Bind private Integer anInt = testValue1;
    200 
    201       @Bind
    202       @SomeQualifier
    203       private Integer anotherInt = testValue2;
    204     };
    205 
    206     BoundFieldModule module = BoundFieldModule.of(instance);
    207     Injector injector = Guice.createInjector(module);
    208 
    209     assertEquals(testValue1, injector.getInstance(Integer.class));
    210     assertEquals(
    211         testValue2,
    212         injector.getInstance(Key.get(Integer.class, SomeQualifier.class)));
    213   }
    214 
    215   public void testCanReuseBindingAnnotationsWithDifferentValues() {
    216     final Integer testValue1 = 1024, testValue2 = 2048;
    217     final String name1 = "foo", name2 = "bar";
    218     Object instance = new Object() {
    219       @Bind
    220       @Named(name1)
    221       private Integer anInt = testValue1;
    222 
    223       @Bind
    224       @Named(name2)
    225       private Integer anotherInt = testValue2;
    226     };
    227 
    228     BoundFieldModule module = BoundFieldModule.of(instance);
    229     Injector injector = Guice.createInjector(module);
    230 
    231     assertEquals(
    232         testValue1,
    233         injector.getInstance(Key.get(Integer.class, Names.named(name1))));
    234     assertEquals(
    235         testValue2,
    236         injector.getInstance(Key.get(Integer.class, Names.named(name2))));
    237   }
    238 
    239   public void testBindingWithValuedBindingAnnotation() {
    240     final Integer testValue1 = 1024, testValue2 = 2048;
    241     final String name = "foo";
    242     Object instance = new Object() {
    243       @Bind private Integer anInt = testValue1;
    244 
    245       @Bind
    246       @Named(name)
    247       private Integer anotherInt = testValue2;
    248     };
    249 
    250     BoundFieldModule module = BoundFieldModule.of(instance);
    251     Injector injector = Guice.createInjector(module);
    252 
    253     assertEquals(testValue1, injector.getInstance(Integer.class));
    254     assertEquals(
    255         testValue2,
    256         injector.getInstance(Key.get(Integer.class, Names.named(name))));
    257   }
    258 
    259   public void testBindingWithGenerics() {
    260     final List<Integer> testIntList = Arrays.asList(new Integer[] {1, 2, 3});
    261     final List<Boolean> testBoolList = Arrays.asList(new Boolean[] {true, true, false});
    262     Object instance = new Object() {
    263       @Bind private List<Integer> anIntList = testIntList;
    264       @Bind private List<Boolean> aBoolList = testBoolList;
    265     };
    266 
    267     BoundFieldModule module = BoundFieldModule.of(instance);
    268     Injector injector = Guice.createInjector(module);
    269 
    270     assertEquals(testIntList, injector.getInstance(new Key<List<Integer>>() {}));
    271     assertEquals(testBoolList, injector.getInstance(new Key<List<Boolean>>() {}));
    272   }
    273 
    274   public void testBoundValueDoesntChange() {
    275     Integer testValue = 1024;
    276     FieldBindableClass instance = new FieldBindableClass(testValue);
    277 
    278     BoundFieldModule module = BoundFieldModule.of(instance);
    279     Injector injector = Guice.createInjector(module);
    280 
    281     assertEquals(testValue, injector.getInstance(Integer.class));
    282     instance.anInt++;
    283     assertEquals(testValue, injector.getInstance(Integer.class));
    284   }
    285 
    286   public void testIncompatibleBindingType() {
    287     final Integer testInt = 1024;
    288     Object instance = new Object() {
    289       @Bind(to = String.class) private Integer anInt = testInt;
    290     };
    291 
    292     BoundFieldModule module = BoundFieldModule.of(instance);
    293 
    294     try {
    295       Guice.createInjector(module);
    296       fail();
    297     } catch (CreationException e) {
    298       assertContains(e.getMessage(),
    299           "Requested binding type \"java.lang.String\" is not assignable from field binding type "
    300           + "\"java.lang.Integer\"");
    301     }
    302   }
    303 
    304   public void testFailureOnMultipleBindingAnnotations() {
    305     final Integer testInt = 1024;
    306     Object instance = new Object() {
    307       @Bind
    308       @Named("a")
    309       @SomeBindingAnnotation
    310       private Integer anInt = testInt;
    311     };
    312 
    313     BoundFieldModule module = BoundFieldModule.of(instance);
    314 
    315     try {
    316       Guice.createInjector(module);
    317     } catch (CreationException e) {
    318       assertContains(e.getMessage(), "More than one annotation is specified for this binding.");
    319     }
    320   }
    321 
    322   public void testBindingSuperTypeAndBindingAnnotation() {
    323     final Integer testValue = 1024;
    324     Object instance = new Object() {
    325       @Bind(to = Number.class)
    326       @Named("foo")
    327       private Integer anInt = testValue;
    328     };
    329 
    330     BoundFieldModule module = BoundFieldModule.of(instance);
    331     Injector injector = Guice.createInjector(module);
    332 
    333     assertEquals(testValue, injector.getInstance(Key.get(Number.class, Names.named("foo"))));
    334   }
    335 
    336   public void testBindingProvider() {
    337     final Integer testValue = 1024;
    338     Object instance = new Object() {
    339       @Bind private Provider<Integer> anInt = new Provider<Integer>() {
    340         @Override public Integer get() {
    341           return testValue;
    342         }
    343       };
    344     };
    345 
    346     BoundFieldModule module = BoundFieldModule.of(instance);
    347     Injector injector = Guice.createInjector(module);
    348 
    349     assertEquals(testValue, injector.getInstance(Integer.class));
    350   }
    351 
    352   public void testBindingNullField() {
    353     Object instance = new Object() {
    354       @Bind private Integer anInt = null;
    355     };
    356 
    357     BoundFieldModule module = BoundFieldModule.of(instance);
    358 
    359     try {
    360       Guice.createInjector(module);
    361       fail();
    362     } catch (CreationException e) {
    363       assertContains(e.getMessage(),
    364           "Binding to null values is not allowed. "
    365           + "Use Providers.of(null) if this is your intended behavior.");
    366     }
    367   }
    368 
    369   public void testBindingNullProvider() {
    370     Object instance = new Object() {
    371       @Bind private Provider<Integer> anIntProvider = null;
    372     };
    373 
    374     BoundFieldModule module = BoundFieldModule.of(instance);
    375 
    376     try {
    377       Guice.createInjector(module);
    378       fail();
    379     } catch (CreationException e) {
    380       assertContains(e.getMessage(),
    381           "Binding to null values is not allowed. "
    382           + "Use Providers.of(null) if this is your intended behavior.");
    383     }
    384   }
    385 
    386   private static class IntegerProvider implements Provider<Integer> {
    387     private final Integer value;
    388 
    389     IntegerProvider(Integer value) {
    390       this.value = value;
    391     }
    392 
    393     @Override public Integer get() {
    394       return value;
    395     }
    396   }
    397 
    398   public void testProviderSubclassesBindToTheProviderItself() {
    399     final IntegerProvider integerProvider = new IntegerProvider(1024);
    400     Object instance = new Object() {
    401       @Bind private IntegerProvider anIntProvider = integerProvider;
    402     };
    403 
    404     BoundFieldModule module = BoundFieldModule.of(instance);
    405     Injector injector = Guice.createInjector(module);
    406 
    407     assertEquals(integerProvider, injector.getInstance(IntegerProvider.class));
    408   }
    409 
    410   public void testProviderSubclassesDoNotBindParameterizedType() {
    411     final Integer testValue = 1024;
    412     Object instance = new Object() {
    413       @Bind private IntegerProvider anIntProvider = new IntegerProvider(testValue);
    414     };
    415 
    416     BoundFieldModule module = BoundFieldModule.of(instance);
    417     Injector injector = Guice.createInjector(module);
    418 
    419     try {
    420       injector.getInstance(Integer.class);
    421       fail();
    422     } catch (ConfigurationException e) {
    423       assertContains(e.getMessage(), "Could not find a suitable constructor in java.lang.Integer.");
    424     }
    425   }
    426 
    427   private static class ParameterizedObject<T> {
    428     ParameterizedObject(T instance) {
    429       this.instance = instance;
    430     }
    431 
    432     @Bind private T instance;
    433   }
    434 
    435   public void testBindParameterizedTypeFails() {
    436     ParameterizedObject<Integer> instance = new ParameterizedObject<Integer>(0);
    437 
    438     BoundFieldModule module = BoundFieldModule.of(instance);
    439 
    440     try {
    441       Guice.createInjector(module);
    442       fail();
    443     } catch (CreationException e) {
    444       assertContains(e.getMessage(), "T cannot be used as a key; It is not fully specified.");
    445     }
    446   }
    447 
    448   public void testBindSubclassOfParameterizedTypeSucceeds() {
    449     final Integer testValue = 1024;
    450     ParameterizedObject<Integer> instance = new ParameterizedObject<Integer>(testValue) {};
    451 
    452     BoundFieldModule module = BoundFieldModule.of(instance);
    453     Injector injector = Guice.createInjector(module);
    454 
    455     assertEquals(testValue, injector.getInstance(Integer.class));
    456   }
    457 
    458   public void testBindArray() {
    459     final Integer[] testArray = new Integer[] { 1024, 2048 };
    460     Object instance = new Object() {
    461       @Bind private Integer[] anIntArray = testArray;
    462     };
    463 
    464     BoundFieldModule module = BoundFieldModule.of(instance);
    465     Injector injector = Guice.createInjector(module);
    466 
    467     assertEquals(testArray, injector.getInstance(Integer[].class));
    468   }
    469 
    470   public void testRawProviderCannotBeBound() {
    471     final Integer testValue = 1024;
    472     Object instance = new Object() {
    473       @Bind private Provider anIntProvider = new Provider() {
    474         @Override public Object get() {
    475           return testValue;
    476         }
    477       };
    478     };
    479 
    480     BoundFieldModule module = BoundFieldModule.of(instance);
    481 
    482     try {
    483       Guice.createInjector(module);
    484       fail();
    485     } catch (CreationException e) {
    486       assertContains(e.getMessage(),
    487           "Non parameterized Provider fields must have an "
    488           + "explicit binding class via @Bind(to = Foo.class)");
    489     }
    490   }
    491 
    492   public void testExplicitlyBoundRawProviderCanBeBound() {
    493     final Integer testValue = 1024;
    494     Object instance = new Object() {
    495       @Bind(to = Integer.class) private Provider anIntProvider = new Provider() {
    496         @Override public Object get() {
    497           return testValue;
    498         }
    499       };
    500     };
    501 
    502     BoundFieldModule module = BoundFieldModule.of(instance);
    503     Injector injector = Guice.createInjector(module);
    504 
    505     assertEquals(testValue, injector.getInstance(Integer.class));
    506   }
    507 
    508   public void testRawProviderCanBindToIncorrectType() {
    509     final Integer testValue = 1024;
    510     Object instance = new Object() {
    511       @Bind(to = String.class) private Provider anIntProvider = new Provider() {
    512         @Override public Object get() {
    513           return testValue;
    514         }
    515       };
    516     };
    517 
    518     BoundFieldModule module = BoundFieldModule.of(instance);
    519     Injector injector = Guice.createInjector(module);
    520 
    521     assertEquals(testValue, injector.getInstance(String.class));
    522   }
    523 
    524   public void testMultipleErrorsAreAggregated() {
    525     Object instance = new Object() {
    526       @Bind private Provider aProvider;
    527       @Bind(to = String.class) private Integer anInt;
    528     };
    529 
    530     BoundFieldModule module = BoundFieldModule.of(instance);
    531     try {
    532       Guice.createInjector(module);
    533     } catch (CreationException e) {
    534       assertEquals(2, e.getErrorMessages().size());
    535     }
    536   }
    537 
    538   public void testBindingProviderWithProviderSubclassValue() {
    539     final Integer testValue = 1024;
    540     Object instance = new Object() {
    541       @Bind private Provider<Integer> anIntProvider = new IntegerProvider(testValue);
    542     };
    543 
    544     BoundFieldModule module = BoundFieldModule.of(instance);
    545     Injector injector = Guice.createInjector(module);
    546 
    547     assertEquals(testValue, injector.getInstance(Integer.class));
    548   }
    549 
    550   public void testBoundFieldsCannotBeInjected() {
    551     Object instance = new Object() {
    552       @Bind
    553       @Inject
    554       Integer anInt = 0;
    555     };
    556 
    557     BoundFieldModule module = BoundFieldModule.of(instance);
    558 
    559     try {
    560       Guice.createInjector(module);
    561     } catch (CreationException e) {
    562       assertContains(
    563           e.getMessage(),
    564           "Fields annotated with both @Bind and @Inject are illegal.");
    565     }
    566   }
    567 
    568   public void testIncrementingProvider() {
    569     final Integer testBaseValue = 1024;
    570     Object instance = new Object() {
    571       @Bind private Provider<Integer> anIntProvider = new Provider<Integer>() {
    572         private int value = testBaseValue;
    573 
    574         @Override public Integer get() {
    575           return value++;
    576         }
    577       };
    578     };
    579 
    580     BoundFieldModule module = BoundFieldModule.of(instance);
    581     Injector injector = Guice.createInjector(module);
    582 
    583     assertEquals(testBaseValue, injector.getInstance(Integer.class));
    584     assertEquals((Integer) (testBaseValue + 1), injector.getInstance(Integer.class));
    585     assertEquals((Integer) (testBaseValue + 2), injector.getInstance(Integer.class));
    586   }
    587 
    588   public void testProviderDoesNotProvideDuringInjectorConstruction() {
    589     Object instance = new Object() {
    590       @Bind private Provider<Integer> myIntProvider = new Provider<Integer>() {
    591         @Override public Integer get() {
    592           throw new UnsupportedOperationException();
    593         }
    594       };
    595     };
    596 
    597     BoundFieldModule module = BoundFieldModule.of(instance);
    598     Guice.createInjector(module);
    599 
    600     // If we don't throw an exception, we succeeded.
    601   }
    602 
    603   private static class InvalidBindableClass {
    604     @Bind(to = String.class) Integer anInt;
    605   }
    606 
    607   public void testIncompatibleBindingTypeStackTraceHasUserFrame() {
    608     Object instance = new InvalidBindableClass();
    609 
    610     BoundFieldModule module = BoundFieldModule.of(instance);
    611 
    612     try {
    613       Guice.createInjector(module);
    614       fail();
    615     } catch (CreationException e) {
    616       assertContains(e.getMessage(), "at " + InvalidBindableClass.class.getName() + " field anInt");
    617     }
    618   }
    619 
    620   private static class InjectedNumberProvider implements Provider<Number> {
    621     @Inject Integer anInt;
    622 
    623     @Override public Number get() {
    624       return anInt;
    625     }
    626   }
    627 
    628   public void testBoundProvidersAreInjected() {
    629     final Integer testValue = 1024;
    630     Object instance = new Object() {
    631       @Bind private Integer anInt = testValue;
    632       @Bind private Provider<Number> aNumberProvider = new InjectedNumberProvider();
    633     };
    634 
    635     BoundFieldModule module = BoundFieldModule.of(instance);
    636     Injector injector = Guice.createInjector(module);
    637 
    638     assertEquals(testValue, injector.getInstance(Number.class));
    639   }
    640 
    641   public void testBoundInstancesAreInjected() {
    642     final Integer testValue = 1024;
    643     final InjectedNumberProvider testNumberProvider = new InjectedNumberProvider();
    644     Object instance = new Object() {
    645       @Bind private Integer anInt = testValue;
    646       @Bind private InjectedNumberProvider aNumberProvider = testNumberProvider;
    647     };
    648 
    649     BoundFieldModule module = BoundFieldModule.of(instance);
    650     Guice.createInjector(module);
    651 
    652     assertEquals(testValue, testNumberProvider.anInt);
    653   }
    654 
    655   private static class InvalidBindableSubclass extends InvalidBindableClass {}
    656 
    657   public void testClassIsPrintedInErrorsWhenCauseIsSuperclass() {
    658     Object instance = new InvalidBindableSubclass();
    659 
    660     BoundFieldModule module = BoundFieldModule.of(instance);
    661 
    662     try {
    663       Guice.createInjector(module);
    664     } catch (CreationException e) {
    665       assertContains(
    666           e.getMessage(),
    667           "Requested binding type \"java.lang.String\" is not assignable from field binding type "
    668           + "\"java.lang.Integer\"");
    669     }
    670   }
    671 
    672   private static class FieldBindableSubclass2 extends FieldBindableClass {
    673     @Bind Number aNumber;
    674 
    675     FieldBindableSubclass2(Integer anInt, Number aNumber) {
    676       super(anInt);
    677       this.aNumber = aNumber;
    678     }
    679   }
    680 
    681   public void testFieldsAreBoundFromFullClassHierarchy() {
    682     final Integer testValue1 = 1024, testValue2 = 2048;
    683     FieldBindableSubclass2 instance = new FieldBindableSubclass2(testValue1, testValue2);
    684 
    685     BoundFieldModule module = BoundFieldModule.of(instance);
    686     Injector injector = Guice.createInjector(module);
    687 
    688     assertEquals(testValue1, injector.getInstance(Integer.class));
    689     assertEquals(testValue2, injector.getInstance(Number.class));
    690   }
    691 
    692   static final class LazyClass {
    693     @Bind(lazy = true) Integer foo = 1;
    694   }
    695 
    696   public void testFieldBound_lazy() {
    697     LazyClass asProvider = new LazyClass();
    698     Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
    699     assertEquals(1, injector.getInstance(Integer.class).intValue());
    700     asProvider.foo++;
    701     assertEquals(2, injector.getInstance(Integer.class).intValue());
    702   }
    703 
    704   public void testFieldBound_lazy_rejectNull() {
    705     LazyClass asProvider = new LazyClass();
    706     Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
    707     assertEquals(1, injector.getInstance(Integer.class).intValue());
    708     asProvider.foo = null;
    709     try {
    710       injector.getInstance(Integer.class);
    711       fail();
    712     } catch (ProvisionException e) {
    713       assertContains(e.getMessage(),
    714           "Binding to null values is not allowed. "
    715           + "Use Providers.of(null) if this is your intended behavior.");
    716     }
    717   }
    718 
    719   static final class LazyProviderClass {
    720     @Bind(lazy = true) Provider<Integer> foo = Providers.of(null);
    721   }
    722 
    723   public void testFieldBoundAsProvider_rejectProvider() {
    724     LazyProviderClass asProvider = new LazyProviderClass();
    725     try {
    726       Guice.createInjector(BoundFieldModule.of(asProvider));
    727       fail();
    728     } catch (CreationException e) {
    729       assertContains(e.getMessage(), "'lazy' is incompatible with Provider valued fields");
    730     }
    731   }
    732 }
    733