/* * Copyright (C) 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.inject; import com.google.inject.internal.Errors; import com.google.inject.name.Named; import com.google.inject.name.Names; import java.io.IOException; import junit.framework.TestCase; /** * Tests that ProvisionExceptions are readable and clearly indicate to the user what went wrong with * their code. * * @author sameb@google.com (Sam Berlin) */ public class ProvisionExceptionsTest extends TestCase { public void testConstructorRuntimeException() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bindConstant().annotatedWith(Names.named("runtime")).to(true); bind(Exploder.class).to(Explosion.class); bind(Tracer.class).to(TracerImpl.class); } }); try { injector.getInstance(Tracer.class); fail(); } catch (ProvisionException pe) { // Make sure our initial error message gives the user exception. Asserts.assertContains( pe.getMessage(), "1) Error injecting constructor", "java.lang.IllegalStateException: boom!"); assertEquals(1, pe.getErrorMessages().size()); assertEquals(IllegalStateException.class, pe.getCause().getClass()); assertEquals( IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass()); } } public void testConstructorCheckedException() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bindConstant().annotatedWith(Names.named("runtime")).to(false); bind(Exploder.class).to(Explosion.class); bind(Tracer.class).to(TracerImpl.class); } }); try { injector.getInstance(Tracer.class); fail(); } catch (ProvisionException pe) { // Make sure our initial error message gives the user exception. Asserts.assertContains( pe.getMessage(), "1) Error injecting constructor", "java.io.IOException: boom!"); assertEquals(1, pe.getErrorMessages().size()); assertEquals(IOException.class, pe.getCause().getClass()); assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass()); } } public void testCustomProvidersRuntimeException() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bind(Exploder.class) .toProvider( new Provider<Exploder>() { @Override public Exploder get() { return Explosion.createRuntime(); } }); bind(Tracer.class).to(TracerImpl.class); } }); try { injector.getInstance(Tracer.class); fail(); } catch (ProvisionException pe) { // Make sure our initial error message gives the user exception. Asserts.assertContains( pe.getMessage(), "1) Error in custom provider", "java.lang.IllegalStateException: boom!"); assertEquals(1, pe.getErrorMessages().size()); assertEquals(IllegalStateException.class, pe.getCause().getClass()); assertEquals( IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass()); } } public void testProviderMethodRuntimeException() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bind(Tracer.class).to(TracerImpl.class); } @Provides Exploder exploder() { return Explosion.createRuntime(); } }); try { injector.getInstance(Tracer.class); fail(); } catch (ProvisionException pe) { // Make sure our initial error message gives the user exception. Asserts.assertContains( pe.getMessage(), "1) Error in custom provider", "java.lang.IllegalStateException: boom!"); assertEquals(1, pe.getErrorMessages().size()); assertEquals(IllegalStateException.class, pe.getCause().getClass()); assertEquals( IllegalStateException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass()); } } public void testProviderMethodCheckedException() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { bind(Tracer.class).to(TracerImpl.class); } @Provides Exploder exploder() throws IOException { return Explosion.createChecked(); } }); try { injector.getInstance(Tracer.class); fail(); } catch (ProvisionException pe) { pe.printStackTrace(); // Make sure our initial error message gives the user exception. Asserts.assertContains( pe.getMessage(), "1) Error in custom provider", "java.io.IOException: boom!"); assertEquals(1, pe.getErrorMessages().size()); assertEquals(IOException.class, pe.getCause().getClass()); assertEquals(IOException.class, Errors.getOnlyCause(pe.getErrorMessages()).getClass()); } } private static interface Exploder {} public static class Explosion implements Exploder { @Inject public Explosion(@Named("runtime") boolean runtime) throws IOException { if (runtime) { throw new IllegalStateException("boom!"); } else { throw new IOException("boom!"); } } public static Explosion createRuntime() { try { return new Explosion(true); } catch (IOException iox) { throw new RuntimeException(); } } public static Explosion createChecked() throws IOException { return new Explosion(false); } } private static interface Tracer {} private static class TracerImpl implements Tracer { @Inject TracerImpl(Exploder explosion) {} } }