diff --git a/README.md b/README.md index 83fbcc5..b5ef1a2 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ To install, you can simply include the dependency from Maven Central: com.redfin insist - 2.0.0 + 2.1.0 ``` @@ -31,8 +31,8 @@ import static com.redfin.insist.Insist.*; ## Assertion vs. Assumption -There are two entry methods when using `Insist`. -They are `assumes()`, and `asserts()` in the `Insist` static class. +There are three entry methods when using `Insist`. +They are `assumes()`, `asserts()`, and `expects()` in the `Insist` static class. The difference is in what will be thrown upon validation failure. ## Stack trace example diff --git a/pom.xml b/pom.xml index 6f2bf30..05d3da2 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ com.redfin insist - 2.0.0 + 2.1.0 4.0.0 jar @@ -76,12 +76,12 @@ com.redfin validity - 4.1.0 + 5.0.0 com.redfin patience - 3.2.0 + 3.3.0 org.opentest4j diff --git a/src/main/java/com/redfin/insist/Insist.java b/src/main/java/com/redfin/insist/Insist.java index 690e9fe..7323b20 100644 --- a/src/main/java/com/redfin/insist/Insist.java +++ b/src/main/java/com/redfin/insist/Insist.java @@ -33,8 +33,10 @@ public final class Insist { private static final BiFunction ASSERT_BI_FUNCTION; private static final BiFunction ASSUME_BI_FUNCTION; + private static final BiFunction EXPECT_BI_FUNCTION; private static final StackTrimmingFailedValidationExecutor ASSERT_EXECUTOR; private static final StackTrimmingFailedValidationExecutor ASSUME_EXECUTOR; + private static final StackTrimmingFailedValidationExecutor EXPECT_EXECUTOR; /* * The null message instances of the factories can be re-used safely. Cache them @@ -43,14 +45,18 @@ public final class Insist { private static final InsistVerifiableFactory NULL_MESSAGE_ASSERT_FACTORY; private static final InsistVerifiableFactory NULL_MESSAGE_ASSUME_FACTORY; + private static final InsistVerifiableFactory NULL_MESSAGE_EXPECT_FACTORY; static { ASSERT_BI_FUNCTION = AssertionFailedError::new; ASSUME_BI_FUNCTION = TestAbortedException::new; + EXPECT_BI_FUNCTION = IllegalStateException::new; ASSERT_EXECUTOR = new StackTrimmingFailedValidationExecutor<>(AssertionFailedError::new); ASSUME_EXECUTOR = new StackTrimmingFailedValidationExecutor<>(TestAbortedException::new); - NULL_MESSAGE_ASSERT_FACTORY = new InsistVerifiableFactory<>(null, ASSERT_BI_FUNCTION, ASSERT_EXECUTOR); - NULL_MESSAGE_ASSUME_FACTORY = new InsistVerifiableFactory<>(null, ASSUME_BI_FUNCTION, ASSUME_EXECUTOR); + EXPECT_EXECUTOR = new StackTrimmingFailedValidationExecutor<>(IllegalStateException::new); + NULL_MESSAGE_ASSERT_FACTORY = new InsistVerifiableFactory<>(() -> null, ASSERT_BI_FUNCTION, ASSERT_EXECUTOR); + NULL_MESSAGE_ASSUME_FACTORY = new InsistVerifiableFactory<>(() -> null, ASSUME_BI_FUNCTION, ASSUME_EXECUTOR); + NULL_MESSAGE_EXPECT_FACTORY = new InsistVerifiableFactory<>(() -> null, EXPECT_BI_FUNCTION, EXPECT_EXECUTOR); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -73,6 +79,14 @@ public static InsistVerifiableFactory assumes() { return NULL_MESSAGE_ASSUME_FACTORY; } + /** + * @return an {@link InsistVerifiableFactory} instance with the default message prefix thatEventually + * throws an {@link IllegalStateException} on validation failure. + */ + public static InsistVerifiableFactory expects() { + return NULL_MESSAGE_EXPECT_FACTORY; + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Instance Methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/main/java/com/redfin/insist/InsistCompletableFutureImpl.java b/src/main/java/com/redfin/insist/InsistCompletableFutureImpl.java index ad9c1db..307fbfd 100644 --- a/src/main/java/com/redfin/insist/InsistCompletableFutureImpl.java +++ b/src/main/java/com/redfin/insist/InsistCompletableFutureImpl.java @@ -22,6 +22,7 @@ import java.time.Duration; import java.util.function.BiFunction; import java.util.function.BooleanSupplier; +import java.util.function.Supplier; import static com.redfin.validity.Validity.validate; @@ -45,7 +46,7 @@ final class InsistCompletableFutureImpl // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final BiFunction throwableFunction; - private final String message; + private final Supplier messageSupplier; private final PatientWait wait; private Duration timeout; @@ -56,17 +57,18 @@ final class InsistCompletableFutureImpl * @param throwableFunction the function to take in a string and throwable and * create a new throwable. * May not be null. - * @param message the String message prefix if validation fails. + * @param messageSupplier the {@link Supplier} of the String message prefix if validation fails. + * May not be null. * @param wait the {@link com.redfin.patience.PatientWait} to use if waiting for validation to succeed. * May not be null. * - * @throws IllegalArgumentException if throwableFunction or wait are null. + * @throws IllegalArgumentException if throwableFunction, messageSupplier, or wait are null. */ InsistCompletableFutureImpl(BiFunction throwableFunction, - String message, + Supplier messageSupplier, PatientWait wait) { this.throwableFunction = validate().that(throwableFunction).isNotNull(); - this.message = message; + this.messageSupplier = validate().that(messageSupplier).isNotNull(); this.wait = validate().that(wait).isNotNull(); this.timeout = wait.getDefaultTimeout(); } @@ -87,7 +89,7 @@ public void thatEventually(BooleanSupplier supplier) throws X { .get(timeout); } catch (PatientTimeoutException exception) { // Failure, throw requested throwable type - throw throwableFunction.apply(fail(message, exception.getAttemptsCount()), exception); + throw throwableFunction.apply(fail(messageSupplier, exception.getAttemptsCount()), exception); } } @@ -115,12 +117,13 @@ public T thatEventuallyThrows(Class expectedThrowableCl }).get(timeout); } catch (PatientTimeoutException exception) { // Failure, throw requested throwable type - throw throwableFunction.apply(fail(message, exception.getAttemptsCount()), exception); + throw throwableFunction.apply(fail(messageSupplier, exception.getAttemptsCount()), exception); } return caught; } - private static String fail(String message, int numAttempts) { + private static String fail(Supplier messageSupplier, int numAttempts) { + String message = messageSupplier.get(); if (null == message) { return String.format(DEFAULT_FORMAT, numAttempts); } else { diff --git a/src/main/java/com/redfin/insist/InsistVerifiableFactory.java b/src/main/java/com/redfin/insist/InsistVerifiableFactory.java index 28cb6f4..728409a 100644 --- a/src/main/java/com/redfin/insist/InsistVerifiableFactory.java +++ b/src/main/java/com/redfin/insist/InsistVerifiableFactory.java @@ -25,6 +25,7 @@ import java.time.Duration; import java.util.Objects; import java.util.function.BiFunction; +import java.util.function.Supplier; import static com.redfin.validity.Validity.validate; @@ -58,7 +59,8 @@ public final class InsistVerifiableFactory /** * Create a new InsistVerifiableFactory instance with the given arguments. * - * @param message the String message prefix for use upon validation failure. + * @param messageSupplier the {@link Supplier} of the String message prefix for use upon validation failure. + * May not be null. * @param throwableFunction the function thatEventually takes in a message and cause and creates * a throwable for failed validation. * May not be null. @@ -68,17 +70,17 @@ public final class InsistVerifiableFactory * * @throws NullPointerException if throwableFunction or failedValidationExecutor are null. */ - InsistVerifiableFactory(String message, + InsistVerifiableFactory(Supplier messageSupplier, BiFunction throwableFunction, FailedValidationExecutor failedValidationExecutor) { - super(message, failedValidationExecutor); + super(messageSupplier, failedValidationExecutor); this.throwableFunction = Objects.requireNonNull(throwableFunction); } @Override - protected InsistVerifiableFactory getFactory(String message, + protected InsistVerifiableFactory getFactory(Supplier messageSupplier, FailedValidationExecutor failedValidationExecutor) { - return new InsistVerifiableFactory<>(message, + return new InsistVerifiableFactory<>(messageSupplier, throwableFunction, failedValidationExecutor); } @@ -92,7 +94,7 @@ protected InsistVerifiableFactory getFactory(String message, */ public InsistCompletableFuture withWait(PatientWait wait) { validate().that(wait).isNotNull(); - return new InsistCompletableFutureImpl<>(throwableFunction, getMessage(), wait); + return new InsistCompletableFutureImpl<>(throwableFunction, getMessageSupplier(), wait); } /** diff --git a/src/main/java/com/redfin/insist/StackTrimmingFailedValidationExecutor.java b/src/main/java/com/redfin/insist/StackTrimmingFailedValidationExecutor.java index e12342d..32d04df 100644 --- a/src/main/java/com/redfin/insist/StackTrimmingFailedValidationExecutor.java +++ b/src/main/java/com/redfin/insist/StackTrimmingFailedValidationExecutor.java @@ -22,6 +22,7 @@ import java.util.OptionalInt; import java.util.function.Function; +import java.util.function.Supplier; import static com.redfin.validity.Validity.validate; @@ -56,7 +57,7 @@ final class StackTrimmingFailedValidationExecutor /** * Create a new instance of a {@link StackTrimmingFailedValidationExecutor} thatEventually - * will use the given throwableFunction when the {@link #fail(String, Object, String)} + * will use the given throwableFunction when the {@link #fail(String, Object, Supplier)} * method is called. * * @param throwableFunction the {@link Function} thatEventually takes in a String and returns a @@ -71,11 +72,17 @@ final class StackTrimmingFailedValidationExecutor } @Override - public void fail(String expected, T subject, String message) throws X { + public void fail(String expected, + T subject, + Supplier messageSupplier) throws X { if (null == expected) { throw new NullPointerException(ValidityUtils.nullArgumentMessage("expected")); } + if (null == messageSupplier) { + throw new NullPointerException(ValidityUtils.nullArgumentMessage("messageSupplier")); + } String subjectDescription = ValidityUtils.describe(subject); + String message = messageSupplier.get(); if (null == message) { message = DEFAULT_MESSAGE; } diff --git a/src/test/java/com/redfin/insist/FailedValidationExecutorContract.java b/src/test/java/com/redfin/insist/FailedValidationExecutorContract.java index 122b19a..fdf4dc6 100644 --- a/src/test/java/com/redfin/insist/FailedValidationExecutorContract.java +++ b/src/test/java/com/redfin/insist/FailedValidationExecutorContract.java @@ -55,24 +55,30 @@ default void testValidationExecutorIsNotNull() { @Test default void testValidationExecutorThrowsExpectedExceptionForNullExpected() { Assertions.assertThrows(NullPointerException.class, - () -> getFailedValidationExecutor().fail(null, "subject", "message")); + () -> getFailedValidationExecutor().fail(null, "subject", () -> "message")); + } + + @Test + default void testValidationExecutorThrowsExpectedExceptionForNullMessageSupplier() { + Assertions.assertThrows(NullPointerException.class, + () -> getFailedValidationExecutor().fail("expected", "subject", null)); } @Test default void testValidationExecutorThrowsExpectedExceptionForNullSubject() { Assertions.assertThrows(getThrowableClass(), - () -> getFailedValidationExecutor().fail("expected", null, "message")); + () -> getFailedValidationExecutor().fail("expected", null, () -> "message")); } @Test default void testValidationExecutorThrowsExpectedExceptionForNullMessage() { Assertions.assertThrows(getThrowableClass(), - () -> getFailedValidationExecutor().fail("expected", "subject", null)); + () -> getFailedValidationExecutor().fail("expected", "subject", () -> null)); } @Test default void testValidationExecutorThrowsExpectedExceptionWithValidArguments() { Assertions.assertThrows(getThrowableClass(), - () -> getFailedValidationExecutor().fail("expected", "subject", "message")); + () -> getFailedValidationExecutor().fail("expected", "subject", () -> "message")); } } diff --git a/src/test/java/com/redfin/insist/InsistTest.java b/src/test/java/com/redfin/insist/InsistTest.java index 06620b7..3cca4dc 100644 --- a/src/test/java/com/redfin/insist/InsistTest.java +++ b/src/test/java/com/redfin/insist/InsistTest.java @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import java.util.function.Supplier; final class InsistTest { @@ -39,17 +40,18 @@ final class InsistTest { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Test - void testInsistAssumeReturnsNonNullFactory() { + void testInsistAssumesReturnsNonNullFactory() { Assertions.assertNotNull(Insist.assumes(), "Insist.assumes() should return a non-null factory."); } @Test - void testInsistAssumeReturnsNullMessageFactory() throws Exception { + @SuppressWarnings("unchecked") + void testInsistAssumesReturnsNullMessageFactory() throws Exception { AbstractVerifiableFactory factory = Insist.assumes(); - Field field = factory.getClass().getSuperclass().getDeclaredField("message"); + Field field = factory.getClass().getSuperclass().getDeclaredField("messageSupplier"); field.setAccessible(true); - Assertions.assertNull(field.get(factory), + Assertions.assertNull(((Supplier) field.get(factory)).get(), "Insist.assumes() should return a factory with a null message."); } @@ -60,14 +62,31 @@ void testInsistAssertsReturnsNonNullFactory() { } @Test + @SuppressWarnings("unchecked") void testInsistAssertsReturnsNullMessageFactory() throws Exception { AbstractVerifiableFactory factory = Insist.asserts(); - Field field = factory.getClass().getSuperclass().getDeclaredField("message"); + Field field = factory.getClass().getSuperclass().getDeclaredField("messageSupplier"); field.setAccessible(true); - Assertions.assertNull(field.get(factory), + Assertions.assertNull(((Supplier) field.get(factory)).get(), "Insist.asserts() should return a factory with a null message."); } + @Test + void testInsistExpectsReturnsNonNullFactory() { + Assertions.assertNotNull(Insist.expects(), + "Insist.expects() should return a non-null factory."); + } + + @Test + @SuppressWarnings("unchecked") + void testInsistExpectsReturnsNullMessageFactory() throws Exception { + AbstractVerifiableFactory factory = Insist.expects(); + Field field = factory.getClass().getSuperclass().getDeclaredField("messageSupplier"); + field.setAccessible(true); + Assertions.assertNull(((Supplier) field.get(factory)).get(), + "Insist.expects() should return a factory with a null message."); + } + @Test void testInsistIsMarkedAsFinal() { Assertions.assertTrue(Modifier.isFinal(Insist.class.getModifiers()), diff --git a/src/test/java/com/redfin/insist/InsistVerifiableFactoryTest.java b/src/test/java/com/redfin/insist/InsistVerifiableFactoryTest.java index bf925b4..85ed45a 100644 --- a/src/test/java/com/redfin/insist/InsistVerifiableFactoryTest.java +++ b/src/test/java/com/redfin/insist/InsistVerifiableFactoryTest.java @@ -23,6 +23,7 @@ import org.opentest4j.AssertionFailedError; import java.time.Duration; +import java.util.function.Supplier; final class InsistVerifiableFactoryTest { @@ -30,13 +31,13 @@ final class InsistVerifiableFactoryTest { // Test helpers // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - private InsistVerifiableFactory getInstance(String message) { - return getInstance(message, new StackTrimmingFailedValidationExecutor<>(AssertionFailedError::new)); + private InsistVerifiableFactory getInstance(Supplier messageSupplier) { + return getInstance(messageSupplier, new StackTrimmingFailedValidationExecutor<>(AssertionFailedError::new)); } - private InsistVerifiableFactory getInstance(String message, - FailedValidationExecutor failedValidationExecutor) { - return new InsistVerifiableFactory<>(message, + private InsistVerifiableFactory getInstance(Supplier messageSupplier, + FailedValidationExecutor failedValidationExecutor) { + return new InsistVerifiableFactory<>(messageSupplier, AssertionFailedError::new, failedValidationExecutor); } @@ -47,20 +48,20 @@ private InsistVerifiableFactory getInstance(String message @Test void testCanInstantiateInsistVerifiableFactory() { - Assertions.assertNotNull(getInstance("message"), + Assertions.assertNotNull(getInstance(() -> "message"), "Should be able to instantiate an InsistVerifiableFactory."); } @Test void testCanInstantiateWithNullMessage() { - Assertions.assertNotNull(getInstance(null), + Assertions.assertNotNull(getInstance(() -> null), "Should be able to instantiate an InsistVerifiableFactory with a null message."); } @Test void testConstructorThrowsExceptionForNullBiFunction() { Assertions.assertThrows(NullPointerException.class, - () -> new InsistVerifiableFactory<>("hello", + () -> new InsistVerifiableFactory<>(() -> "hello", null, new StackTrimmingFailedValidationExecutor<>(AssertionFailedError::new)), "InsistVerifiableFactory constructor should throw exception for null bi-function."); @@ -69,7 +70,7 @@ void testConstructorThrowsExceptionForNullBiFunction() { @Test void testConstructorThrowsExceptionForNullFailedValidationExecutor() { Assertions.assertThrows(NullPointerException.class, - () -> new InsistVerifiableFactory<>("hello", + () -> new InsistVerifiableFactory<>(() -> "hello", AssertionFailedError::new, null), "InsistVerifiableFactory constructor should throw exception for null failed validation executor."); @@ -77,7 +78,7 @@ void testConstructorThrowsExceptionForNullFailedValidationExecutor() { @Test void testGetFactoryReturnsANonNullInstance() { - Assertions.assertNotNull(getInstance("message").getFactory("newMessage", + Assertions.assertNotNull(getInstance(() -> "message").getFactory(() -> "newMessage", new StackTrimmingFailedValidationExecutor<>(AssertionFailedError::new)), "InsistVerifiableFactory getFactory should return a non-null instance."); } @@ -85,61 +86,61 @@ void testGetFactoryReturnsANonNullInstance() { @Test void testGetFactoryThrowsExceptionForNullFailedValidationExecutor() { Assertions.assertThrows(NullPointerException.class, - () -> getInstance("message").getFactory("newMessage", null), + () -> getInstance(() -> "message").getFactory(() -> "newMessage", null), "InsistVerifiableFactory getFactory should throw exception for null failed validation executor."); } @Test void testWithWaitReturnsANonNullInstance() { - Assertions.assertNotNull(getInstance("message").withWait(PatientWait.builder().build()), + Assertions.assertNotNull(getInstance(() -> "message").withWait(PatientWait.builder().build()), "InsistVerifiableFactory withWait should return a non-null instance."); } @Test void testWithWaitThrowsExceptionForNullWait() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").withWait(null), + () -> getInstance(() -> "message").withWait(null), "InsistVerifiableFactory withWait should throw exception for null wait."); } @Test void testWithinReturnsANonNullInstance() { - Assertions.assertNotNull(getInstance("message").within(Duration.ofMillis(100)), + Assertions.assertNotNull(getInstance(() -> "message").within(Duration.ofMillis(100)), "InsistVerifiableFactory within should return a non-null instance."); } @Test void testWithinThrowsExceptionForNullTryingFor() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").within(null), + () -> getInstance(() -> "message").within(null), "InsistVerifiableFactory within should throw exception for null tryingFor."); } @Test void testWithinThrowsExceptionForNegativeTryingFor() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").within(Duration.ofMillis(100).negated()), + () -> getInstance(() -> "message").within(Duration.ofMillis(100).negated()), "InsistVerifiableFactory within should throw exception for negative tryingFor."); } @Test void testThatThrowsExceptionForNullExpectedClass() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").thatThrows(null, () -> {}), + () -> getInstance(() -> "message").thatThrows(null, () -> {}), "InsistVerifiableFactory thatThrows should throw exception for null expected class."); } @Test void testThatThrowsThrowsExceptionForNullExecutable() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").thatThrows(IllegalArgumentException.class, null), + () -> getInstance(() -> "message").thatThrows(IllegalArgumentException.class, null), "InsistVerifiableFactory thatThrows should throw exception for null executable."); } @Test void testThatThrowsThrowsExceptionForExecutableThatDoesNotThrowExpected() { Assertions.assertThrows(IllegalArgumentException.class, - () -> getInstance("message").thatThrows(null, () -> {}), + () -> getInstance(() -> "message").thatThrows(null, () -> {}), "InsistVerifiableFactory thatThrows should throw exception for null expected class."); } @@ -148,7 +149,7 @@ void testThatThrowsThrowsExceptionForExecutableThatDoesNotThrowExpected() { void testThatThrowsReturnsExpectedThrowableIfThrown() { String message = "whoops"; Assertions.assertEquals(message, - getInstance("message").thatThrows(IllegalArgumentException.class, + getInstance(() -> "message").thatThrows(IllegalArgumentException.class, () -> { throw new IllegalArgumentException("whoops"); }) .getMessage(), "InsistFuture thatEventuallyThrows should return the thrown expected exception."); diff --git a/src/test/java/com/redfin/insist/StackTrimmingFailedValidationExecutorTest.java b/src/test/java/com/redfin/insist/StackTrimmingFailedValidationExecutorTest.java index 6b00d0c..be0ff11 100644 --- a/src/test/java/com/redfin/insist/StackTrimmingFailedValidationExecutorTest.java +++ b/src/test/java/com/redfin/insist/StackTrimmingFailedValidationExecutorTest.java @@ -39,7 +39,7 @@ default void testThrownExceptionHasExpectedMessage() { String subject = "subject"; String message = "message"; X throwable = Assertions.assertThrows(getThrowableClass(), - () -> getFailedValidationExecutor().fail(expected, subject, message)); + () -> getFailedValidationExecutor().fail(expected, subject, () -> message)); Assertions.assertEquals(String.format(MESSAGE_FORMAT, message, expected, @@ -53,7 +53,7 @@ default void testThrownExceptionHasExpectedMessageWithNullMessage() { String expected = "expected"; String subject = "subject"; X throwable = Assertions.assertThrows(getThrowableClass(), - () -> getFailedValidationExecutor().fail(expected, subject, null)); + () -> getFailedValidationExecutor().fail(expected, subject, () -> null)); Assertions.assertTrue(null != throwable.getMessage() && throwable.getMessage().startsWith("Insistence failure"), "Expected the thrown throwable for validation failure to start with the expected message."); } @@ -62,7 +62,7 @@ default void testThrownExceptionHasExpectedMessageWithNullMessage() { default void testFailedValidationExecutorThrowsForNullThrowable() { FailedValidationExecutor executor = new StackTrimmingFailedValidationExecutor<>(message -> null); Assertions.assertThrows(NullPointerException.class, - () -> executor.fail("expected", "subject", "message")); + () -> executor.fail("expected", "subject", () -> "message")); } } @@ -87,7 +87,7 @@ default void testValidationExecutorCanHandleEmptyStackTraceFromException() { String subject = "subject"; String message = "message"; Assertions.assertThrows(NoStackRuntimeException.class, - () -> getNoStackFailedValidationExecutor().fail(expected, subject, message)); + () -> getNoStackFailedValidationExecutor().fail(expected, subject, () -> message)); } } @@ -125,7 +125,7 @@ void throwsExceptionForNullThrowableFunction() { @Test void testFailedValidationExecutorThrowsExceptionForNullThrowableCreation() { NullPointerException exception = Assertions.assertThrows(NullPointerException.class, - () -> new DefaultValidityFailedValidationExecutor<>(str -> null).fail("", "", "")); + () -> new DefaultValidityFailedValidationExecutor<>(str -> null).fail("", "", () -> "")); Assertions.assertEquals(ValidityUtils.nullThrowableFromFunction(), exception.getMessage(), "Failed validation executors should throw the expected exception for a null throwable created.");