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@google.com (Sam Berlin) 32 */ 33 public class ProvisionExceptionsTest extends TestCase { 34 testConstructorRuntimeException()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 testConstructorCheckedException()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 testCustomProvidersRuntimeException()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 testProviderMethodRuntimeException()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 testProviderMethodCheckedException()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 { Explosion(@amed"runtime") boolean runtime)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 createRuntime()161 public static Explosion createRuntime() { 162 try { 163 return new Explosion(true); 164 } catch(IOException iox) { 165 throw new RuntimeException(); 166 } 167 } 168 createChecked()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 { TracerImpl(Exploder explosion)175 @Inject TracerImpl(Exploder explosion) { 176 } 177 } 178 } 179