From 9e3d8069909f14ec35edd156559dee629571b581 Mon Sep 17 00:00:00 2001 From: Nicholas Lativy Date: Mon, 27 Apr 2026 21:10:21 +0100 Subject: [PATCH 1/2] Migrate ExpectedException to assertThrows ExpectedException has been deprecated since JUnit 4.13 in favor of assertThrows, which scopes the expectation to a specific call rather than the whole test method. Convert all uses across the test suite plus two equivalent try/catch+fail() blocks in AcaiTest. Where relevant, hoist non-throwing setup out of the assertThrows lambda to satisfy Error Prone's AssertThrowsMinimizer. --- src/test/java/com/google/acai/AcaiTest.java | 41 ++++++++----------- .../com/google/acai/DependenciesTest.java | 12 +++--- .../java/com/google/acai/TestScopeTest.java | 12 +++--- .../acai/TestingServiceManagerTest.java | 22 +++++----- 4 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/test/java/com/google/acai/AcaiTest.java b/src/test/java/com/google/acai/AcaiTest.java index 270d154..7698c75 100644 --- a/src/test/java/com/google/acai/AcaiTest.java +++ b/src/test/java/com/google/acai/AcaiTest.java @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -31,9 +32,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @@ -42,7 +41,6 @@ @RunWith(MockitoJUnitRunner.class) public class AcaiTest { - @Rule public ExpectedException thrown = ExpectedException.none(); @Mock private Statement statement; @Mock private FrameworkMethod frameworkMethod; @@ -95,12 +93,8 @@ public void testCaseIsInjected() throws Throwable { @Test public void failingTestInjectionDoesNotAffectSubsequentTests() throws Throwable { Acai acai = new Acai(TestModule.class); - try { - acai.apply(statement, frameworkMethod, new TestWithUnsatisfiedBinding()).evaluate(); - assertWithMessage("Expected ConfigurationException to be thrown.").fail(); - } catch (ConfigurationException e) { - // Expected: TestWithUnsatisfiedBinding requires binding not satisfied by TestModule. - } + Statement failing = acai.apply(statement, frameworkMethod, new TestWithUnsatisfiedBinding()); + assertThrows(ConfigurationException.class, failing::evaluate); acai.apply(statement, frameworkMethod, new ExampleTest()).evaluate(); @@ -110,12 +104,8 @@ public void failingTestInjectionDoesNotAffectSubsequentTests() throws Throwable @Test public void failingBeforeTestMethodDoesNotAffectSubsequentTests() throws Throwable { Acai acai = new Acai(FailingBeforeTestModule.class); - try { - acai.apply(statement, frameworkMethod, new ExampleTest()).evaluate(); - assertWithMessage("Expected TestException to be thrown.").fail(); - } catch (TestException e) { - // Expected: ServiceWithFailingBeforeTest throws TestException in @BeforeTest. - } + Statement failing = acai.apply(statement, frameworkMethod, new ExampleTest()); + assertThrows(TestException.class, failing::evaluate); ServiceWithFailingBeforeTest.shouldFail = false; acai.apply(statement, frameworkMethod, new ExampleTest()).evaluate(); @@ -146,19 +136,20 @@ public void servicesRunInDependencyOrder() throws Throwable { } @Test - public void usefulErrorMessageWhenModuleMissingZeroArgConstructor() throws Throwable { - thrown.expectMessage("does not have zero argument constructor"); - new Acai(ModuleWithoutZeroArgumentConstructor.class) - .apply(statement, frameworkMethod, new Object()) - .evaluate(); + public void usefulErrorMessageWhenModuleMissingZeroArgConstructor() { + Statement runner = + new Acai(ModuleWithoutZeroArgumentConstructor.class) + .apply(statement, frameworkMethod, new Object()); + RuntimeException e = assertThrows(RuntimeException.class, runner::evaluate); + assertThat(e).hasMessageThat().contains("does not have zero argument constructor"); } @Test - public void rethrowsExceptionThrownByModuleConstructor() throws Throwable { - thrown.expect(TestException.class); - new Acai(ModuleWithThrowingConstructor.class) - .apply(statement, frameworkMethod, new Object()) - .evaluate(); + public void rethrowsExceptionThrownByModuleConstructor() { + Statement runner = + new Acai(ModuleWithThrowingConstructor.class) + .apply(statement, frameworkMethod, new Object()); + assertThrows(TestException.class, runner::evaluate); } @Test diff --git a/src/test/java/com/google/acai/DependenciesTest.java b/src/test/java/com/google/acai/DependenciesTest.java index 6c44901..7f5918f 100644 --- a/src/test/java/com/google/acai/DependenciesTest.java +++ b/src/test/java/com/google/acai/DependenciesTest.java @@ -17,21 +17,18 @@ package com.google.acai; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import java.util.Set; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class DependenciesTest { - @Rule public ExpectedException thrown = ExpectedException.none(); - private static class ServiceA implements TestingService {} private static class ServiceB implements TestingService {} @@ -98,8 +95,9 @@ private static class C implements TestingService {} @Test public void throwsExceptionIfCyclePresent() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Cycle"); - Dependencies.inOrder(ImmutableSet.of(new A(), new B(), new C())); + ImmutableSet services = ImmutableSet.of(new A(), new B(), new C()); + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> Dependencies.inOrder(services)); + assertThat(e).hasMessageThat().contains("Cycle"); } } diff --git a/src/test/java/com/google/acai/TestScopeTest.java b/src/test/java/com/google/acai/TestScopeTest.java index ac69559..0c22311 100644 --- a/src/test/java/com/google/acai/TestScopeTest.java +++ b/src/test/java/com/google/acai/TestScopeTest.java @@ -17,6 +17,7 @@ package com.google.acai; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import com.google.inject.AbstractModule; import com.google.inject.Provider; @@ -24,9 +25,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @@ -35,7 +34,6 @@ @RunWith(MockitoJUnitRunner.class) public class TestScopeTest { - @Rule public ExpectedException thrown = ExpectedException.none(); @Mock private Statement statement; @Mock private FrameworkMethod frameworkMethod; @@ -61,12 +59,12 @@ public void differentInstanceInjectedAcrossTests() throws Throwable { } @Test - public void servicesInstantiatedOutsideTestScope() throws Throwable { + public void servicesInstantiatedOutsideTestScope() { FakeTestClass test = new FakeTestClass(); + Statement runner = new Acai(InvalidTestModule.class).apply(statement, frameworkMethod, test); - thrown.expect(ProvisionException.class); - thrown.expectMessage("@TestScoped binding outside test"); - new Acai(InvalidTestModule.class).apply(statement, frameworkMethod, test).evaluate(); + ProvisionException e = assertThrows(ProvisionException.class, runner::evaluate); + assertThat(e).hasMessageThat().contains("@TestScoped binding outside test"); } @Test diff --git a/src/test/java/com/google/acai/TestingServiceManagerTest.java b/src/test/java/com/google/acai/TestingServiceManagerTest.java index 3a11624..c603ecb 100644 --- a/src/test/java/com/google/acai/TestingServiceManagerTest.java +++ b/src/test/java/com/google/acai/TestingServiceManagerTest.java @@ -17,17 +17,14 @@ package com.google.acai; import static com.google.common.truth.Truth.assertThat; -import static org.hamcrest.Matchers.isA; +import static org.junit.Assert.assertThrows; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class TestingServiceManagerTest { - @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void callBeforeSuiteMethod() { @@ -93,28 +90,29 @@ public void methodsFoundThroughSubclass() { @Test public void runtimeExceptionsPropagated() { - thrown.expect(TestRuntimeException.class); - new TestingServiceManager( + TestingServiceManager manager = + new TestingServiceManager( new TestingService() { @BeforeTest void beforeTest() { throw new TestRuntimeException(); } - }) - .beforeTest(); + }); + assertThrows(TestRuntimeException.class, manager::beforeTest); } @Test public void checkedExceptionsPropagatedInsideRuntimeException() { - thrown.expectCause(isA(TestException.class)); - new TestingServiceManager( + TestingServiceManager manager = + new TestingServiceManager( new TestingService() { @BeforeTest void beforeTest() throws TestException { throw new TestException(); } - }) - .beforeTest(); + }); + RuntimeException e = assertThrows(RuntimeException.class, manager::beforeTest); + assertThat(e).hasCauseThat().isInstanceOf(TestException.class); } @Test From c2703f79a84bd5e3b122b8d01a4a557a28215a74 Mon Sep 17 00:00:00 2001 From: Nicholas Lativy Date: Mon, 27 Apr 2026 21:14:07 +0100 Subject: [PATCH 2/2] Drop unused hamcrest dependency The only direct hamcrest reference was the isA matcher in TestingServiceManagerTest, which went away with the assertThrows migration. JUnit 4 still pulls in hamcrest-core transitively, so the explicit org.hamcrest:hamcrest:3.0 dep is no longer earning its keep. --- pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pom.xml b/pom.xml index ae33a46..f686ac5 100644 --- a/pom.xml +++ b/pom.xml @@ -202,12 +202,6 @@ 5.23.0 test - - org.hamcrest - hamcrest - 3.0 - test - javax.inject javax.inject