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