package com.google.inject.testing.throwingproviders; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.truth.FailureStrategy; import com.google.inject.throwingproviders.CheckedProvider; import com.google.inject.throwingproviders.CheckedProviders; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Unit tests for {@link CheckedProviderSubject}. * * @author eatnumber1@google.com (Russ Harmon) */ @RunWith(JUnit4.class) public class CheckedProviderSubjectTest { private static final class FailureStrategyException extends RuntimeException { FailureStrategyException() {} FailureStrategyException(String message, Throwable cause) { super(message, cause); } } private static final class ThrowingFailureStrategy extends FailureStrategy { @Override public void fail(String message, Throwable cause) { throw new FailureStrategyException(message, cause); } } private interface StringCheckedProvider extends CheckedProvider<String> {} @Test public void providedValue_gotExpected_expectSuccess() { String expected = "keep Summer safe"; CheckedProvider<String> provider = CheckedProviders.of(StringCheckedProvider.class, expected); createSubject(provider).providedValue().isEqualTo(expected); } @Test public void providedValue_gotUnexpected_expectFailure() { String expected = "keep Summer safe"; String unexpected = "Summer is unsafe"; CheckedProvider<String> provider = CheckedProviders.of(StringCheckedProvider.class, unexpected); String message = String.format( "value provided by <%s>: Not true that <%s> is equal to <%s>", getReturningProviderName(unexpected), unexpected, expected); try { createSubject(provider).providedValue().isEqualTo(expected); fail("Expected an exception to be thrown"); } catch (FailureStrategyException e) { assertThat(e).hasMessage(message); } } private static final class SummerException extends RuntimeException {} @Test public void providedValue_throws_expectFailure() { CheckedProvider<?> provider = CheckedProviders.throwing(StringCheckedProvider.class, SummerException.class); String message = String.format( "checked provider <%s> threw an exception", getThrowingProviderName(SummerException.class.getName())); try { createSubject(provider).providedValue(); fail("Expected an exception to be thrown"); } catch (FailureStrategyException e) { assertThat(e.getCause()).isInstanceOf(SummerException.class); assertThat(e).hasMessage(message); } } @Test public void thrownException_threwExpected_expectSuccess() { CheckedProvider<?> provider = CheckedProviders.throwing(StringCheckedProvider.class, SummerException.class); createSubject(provider).thrownException().isInstanceOf(SummerException.class); } @Test public void thrownException_threwUnexpected_expectFailure() { Class<? extends Throwable> expected = SummerException.class; Class<? extends Throwable> unexpected = UnsupportedOperationException.class; CheckedProvider<?> provider = CheckedProviders.throwing(StringCheckedProvider.class, unexpected); String message = String.format( "exception thrown by <%s>: Not true that <%s> is an instance of <%s>. " + "It is an instance of <%s>", getThrowingProviderName(UnsupportedOperationException.class.getName()), UnsupportedOperationException.class.getName(), SummerException.class.getName(), UnsupportedOperationException.class.getName()); try { createSubject(provider).thrownException().isInstanceOf(expected); fail("Expected an exception to be thrown"); } catch (FailureStrategyException e) { assertThat(e).hasMessage(message); } } @Test public void thrownException_gets_expectFailure() { String getValue = "keep WINTER IS COMING safe"; CheckedProvider<?> provider = CheckedProviders.of(StringCheckedProvider.class, getValue); String message = String.format( "Not true that <%s> threw <an exception>. It provided <%s>", getReturningProviderName(getValue), getValue); try { createSubject(provider).thrownException(); fail("Expected an exception to be thrown"); } catch (FailureStrategyException e) { assertThat(e).hasMessage(message); } } private <T, P extends CheckedProvider<T>> CheckedProviderSubject<T, P> createSubject(P provider) { return new CheckedProviderSubject<T, P>(new ThrowingFailureStrategy(), provider); } private String getReturningProviderName(String providing) { return String.format("generated CheckedProvider returning <%s>", providing); } private String getThrowingProviderName(String throwing) { return String.format("generated CheckedProvider throwing <%s>", throwing); } }