blob: 1498de6c99a127ad0c39e8de5b56cb664129506a [file] [log] [blame]
// Copyright 2018 The Feed Authors.
//
// 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.android.libraries.feed.common.testing;
import static com.google.android.libraries.feed.common.testing.RunnableSubject.assertThatRunnable;
import static com.google.android.libraries.feed.common.testing.RunnableSubject.runnables;
import static com.google.common.truth.ExpectFailure.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import com.google.android.libraries.feed.common.testing.RunnableSubject.ThrowingRunnable;
import com.google.common.truth.ExpectFailure;
import com.google.common.truth.Truth;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.junit.ComparisonFailure;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link RunnableSubject}. */
@RunWith(JUnit4.class)
public class RunnableSubjectTest {
@Rule public final ExpectFailure expectFailure = new ExpectFailure();
@Test
public void runToCompletion() throws Throwable {
ThrowingRunnable run = mock(ThrowingRunnable.class);
expectFailure
.whenTesting()
.about(runnables())
.that(run)
.throwsAnExceptionOfType(RuntimeException.class);
verify(run).run();
AssertionError failure = expectFailure.getFailure();
assertThat(failure).factValue("expected to throw").isEqualTo("java.lang.RuntimeException");
assertThat(failure).factKeys().contains("but ran to completion");
verifyNoMoreInteractions(run);
}
@Test
public void nullSubjectFailsEvenWhenExpectingNullRefException() {
expectFailure
.whenTesting()
.about(runnables())
.that(null)
.throwsAnExceptionOfType(NullPointerException.class);
AssertionError failure = expectFailure.getFailure();
assertThat(failure).factValue("expected to throw").isEqualTo("java.lang.NullPointerException");
assertThat(failure).factKeys().contains("but didn't run because it's null");
}
@Test
public void wrongException() {
expectFailure
.whenTesting()
.about(runnables())
.that(
() -> {
throw new IllegalArgumentException("a");
})
.throwsAnExceptionOfType(NullPointerException.class);
AssertionError failure = expectFailure.getFailure();
assertThat(failure).factValue("value of").isEqualTo("runnable.thrownException()");
assertThat(failure)
.factValue("expected instance of")
.isEqualTo("java.lang.NullPointerException");
assertThat(failure)
.factValue("but was instance of")
.isEqualTo("java.lang.IllegalArgumentException");
assertThat(failure).factValue("with value").isEqualTo("java.lang.IllegalArgumentException: a");
}
@Test
public void correctException() {
IllegalArgumentException ex = new IllegalArgumentException("b");
Truth.assertAbout(runnables())
.that(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IllegalArgumentException.class)
.that()
.isSameInstanceAs(ex);
}
@Test
public void wrongMessage() {
expectFailure
.whenTesting()
.about(runnables())
.that(
() -> {
throw new IOException("Wrong message!");
})
.throwsAnExceptionOfType(IOException.class)
.that()
.hasMessageThat()
.isEqualTo("Expected message.");
ComparisonFailure failure = (ComparisonFailure) expectFailure.getFailure();
assertThat(failure.getExpected()).isEqualTo("Expected message.");
assertThat(failure.getActual()).isEqualTo("Wrong message!");
}
@Test
public void correctMessage() {
String expectedMessage = "Expected message.";
Truth.assertAbout(runnables())
.that(
() -> {
throw new IOException(expectedMessage);
})
.throwsAnExceptionOfType(IOException.class)
.that()
.hasMessageThat()
.isEqualTo(expectedMessage);
}
@Test
public void getCaught() {
IllegalArgumentException cause = new IllegalArgumentException("boo");
IOException ex = new IOException(cause);
IOException caught =
RunnableSubject.assertThat(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IOException.class)
.getCaught();
assertThat(caught).isSameInstanceAs(ex);
}
@Test
public void wrongCauseType() {
IllegalArgumentException cause = new IllegalArgumentException("boo");
IOException ex = new IOException(cause);
expectFailure
.whenTesting()
.about(runnables())
.that(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IOException.class)
.causedByAnExceptionOfType(ExecutionException.class);
AssertionError failure = expectFailure.getFailure();
assertThat(failure).factValue("value of").isEqualTo("runnable.thrownException().getCause()");
assertThat(failure)
.factValue("expected instance of")
.isEqualTo("java.util.concurrent.ExecutionException");
assertThat(failure)
.factValue("but was instance of")
.isEqualTo("java.lang.IllegalArgumentException");
assertThat(failure)
.factValue("with value")
.isEqualTo("java.lang.IllegalArgumentException: boo");
}
@Test
public void correctCauseType() {
IllegalArgumentException cause = new IllegalArgumentException("boo");
IOException ex = new IOException(cause);
Truth.assertAbout(runnables())
.that(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IOException.class)
.causedByAnExceptionOfType(IllegalArgumentException.class)
.that()
.hasMessageThat()
.isEqualTo("boo");
}
@Test
public void causedByCorrect() {
IOException cause = new IOException();
IllegalArgumentException ex = new IllegalArgumentException(cause);
Truth.assertAbout(runnables())
.that(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IllegalArgumentException.class)
.causedBy(cause);
}
@Test
public void causedByWrong() {
IOException cause = new IOException();
IllegalArgumentException ex = new IllegalArgumentException(cause);
expectFailure
.whenTesting()
.about(runnables())
.that(
() -> {
throw ex;
})
.throwsAnExceptionOfType(IllegalArgumentException.class)
.causedBy(new IOException());
}
@Test
public void exampleUsage() {
assertThatRunnable(
() -> {
throw new IOException("boo!");
})
.throwsAnExceptionOfType(IOException.class)
.that()
.hasMessageThat()
.isEqualTo("boo!");
RunnableSubject.assertThat(
() -> {
throw new IllegalArgumentException("oh no");
})
.throwsAnExceptionOfType(IllegalArgumentException.class)
.that()
.hasMessageThat()
.isEqualTo("oh no");
RunnableSubject.assertThat(
() -> {
throw new IllegalArgumentException(new RuntimeException("glitch"));
})
.throwsAnExceptionOfType(IllegalArgumentException.class)
.causedByAnExceptionOfType(RuntimeException.class)
.that()
.hasMessageThat()
.isEqualTo("glitch");
// Recursive self-verification.
RunnableSubject.assertThat(
() ->
RunnableSubject.assertThat(() -> {})
.throwsAnExceptionOfType(RuntimeException.class))
.throwsAnExceptionOfType(AssertionError.class);
}
}