Home | History | Annotate | Download | only in inject
      1 /**
      2  * Copyright (C) 2010 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 com.google.inject.internal.Errors;
     20 import com.google.inject.name.Named;
     21 import com.google.inject.name.Names;
     22 
     23 import junit.framework.TestCase;
     24 
     25 import java.io.IOException;
     26 
     27 /**
     28  * Tests that ProvisionExceptions are readable and clearly indicate to the user what went wrong with
     29  * their code.
     30  *
     31  * @author sameb (at) google.com (Sam Berlin)
     32  */
     33 public class ProvisionExceptionsTest extends TestCase {
     34 
     35   public void testConstructorRuntimeException() {
     36     Injector injector = Guice.createInjector(new AbstractModule() {
     37       @Override
     38       protected void configure() {
     39         bindConstant().annotatedWith(Names.named("runtime")).to(true);
     40         bind(Exploder.class).to(Explosion.class);
     41         bind(Tracer.class).to(TracerImpl.class);
     42       }
     43     });
     44     try {
     45       injector.getInstance(Tracer.class);
     46       fail();
     47     } catch(ProvisionException pe) {
     48       // Make sure our initial error message gives the user exception.
     49       Asserts.assertContains(pe.getMessage(),
     50           "1) Error injecting constructor", "java.lang.IllegalStateException: boom!");
     51       assertEquals(1, pe.getErrorMessages().size());
     52       assertEquals(IllegalStateException.class, pe.getCause().getClass());
     53       assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
     54     }
     55   }
     56 
     57   public void testConstructorCheckedException() {
     58     Injector injector = Guice.createInjector(new AbstractModule() {
     59       @Override
     60       protected void configure() {
     61         bindConstant().annotatedWith(Names.named("runtime")).to(false);
     62         bind(Exploder.class).to(Explosion.class);
     63         bind(Tracer.class).to(TracerImpl.class);
     64       }
     65     });
     66     try {
     67       injector.getInstance(Tracer.class);
     68       fail();
     69     } catch(ProvisionException pe) {
     70       // Make sure our initial error message gives the user exception.
     71       Asserts.assertContains(pe.getMessage(),
     72           "1) Error injecting constructor", "java.io.IOException: boom!");
     73       assertEquals(1, pe.getErrorMessages().size());
     74       assertEquals(IOException.class, pe.getCause().getClass());
     75       assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
     76     }
     77   }
     78 
     79   public void testCustomProvidersRuntimeException() {
     80     Injector injector = Guice.createInjector(new AbstractModule() {
     81       @Override
     82       protected void configure() {
     83         bind(Exploder.class).toProvider(new Provider<Exploder>() {
     84           public Exploder get() {
     85             return Explosion.createRuntime();
     86           }
     87         });
     88         bind(Tracer.class).to(TracerImpl.class);
     89       }
     90     });
     91     try {
     92       injector.getInstance(Tracer.class);
     93       fail();
     94     } catch(ProvisionException pe) {
     95       // Make sure our initial error message gives the user exception.
     96       Asserts.assertContains(pe.getMessage(),
     97           "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
     98       assertEquals(1, pe.getErrorMessages().size());
     99       assertEquals(IllegalStateException.class, pe.getCause().getClass());
    100       assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
    101     }
    102   }
    103 
    104   public void testProviderMethodRuntimeException() {
    105     Injector injector = Guice.createInjector(new AbstractModule() {
    106       @Override
    107       protected void configure() {
    108         bind(Tracer.class).to(TracerImpl.class);
    109       }
    110       @Provides Exploder exploder() {
    111         return Explosion.createRuntime();
    112       }
    113     });
    114     try {
    115       injector.getInstance(Tracer.class);
    116       fail();
    117     } catch(ProvisionException pe) {
    118       // Make sure our initial error message gives the user exception.
    119       Asserts.assertContains(pe.getMessage(),
    120           "1) Error in custom provider", "java.lang.IllegalStateException: boom!");
    121       assertEquals(1, pe.getErrorMessages().size());
    122       assertEquals(IllegalStateException.class, pe.getCause().getClass());
    123       assertEquals(IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
    124     }
    125   }
    126 
    127   public void testProviderMethodCheckedException() {
    128     Injector injector = Guice.createInjector(new AbstractModule() {
    129       @Override
    130       protected void configure() {
    131         bind(Tracer.class).to(TracerImpl.class);
    132       }
    133       @Provides Exploder exploder() throws IOException {
    134         return Explosion.createChecked();
    135       }
    136     });
    137     try {
    138       injector.getInstance(Tracer.class);
    139       fail();
    140     } catch(ProvisionException pe) {
    141       pe.printStackTrace();
    142       // Make sure our initial error message gives the user exception.
    143       Asserts.assertContains(pe.getMessage(),
    144           "1) Error in custom provider", "java.io.IOException: boom!");
    145       assertEquals(1, pe.getErrorMessages().size());
    146       assertEquals(IOException.class, pe.getCause().getClass());
    147       assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass());
    148     }
    149   }
    150 
    151   private static interface Exploder {}
    152   public static class Explosion implements Exploder {
    153     @Inject public Explosion(@Named("runtime") boolean runtime) throws IOException {
    154       if(runtime) {
    155         throw new IllegalStateException("boom!");
    156       } else {
    157         throw new IOException("boom!");
    158       }
    159     }
    160 
    161     public static Explosion createRuntime() {
    162       try {
    163         return new Explosion(true);
    164       } catch(IOException iox) {
    165         throw new RuntimeException();
    166       }
    167     }
    168 
    169     public static Explosion createChecked() throws IOException {
    170       return new Explosion(false);
    171     }
    172   }
    173   private static interface Tracer {}
    174   private static class TracerImpl implements Tracer {
    175     @Inject TracerImpl(Exploder explosion) {
    176     }
    177   }
    178 }
    179