Streamline assertions on exceptions

This commit simplifies assertions on MockMvc requests that have failed
to process. A now general hasFailed/doesNotHaveFailed/failure provides
the necessary to assert the exception.

Any attempt to access anything from the result with an unresolved
exception still fails as before.

Closes gh-33060
This commit is contained in:
Stéphane Nicoll
2024-06-18 06:23:13 +02:00
parent 6561490fd9
commit 84bcb65dd1
3 changed files with 70 additions and 30 deletions

View File

@@ -89,12 +89,20 @@ import org.springframework.web.context.WebApplicationContext;
* <p>One main difference between {@link MockMvc} and {@code MockMvcTester} is
* that an unresolved exception is not thrown directly when using
* {@code MockMvcTester}. Rather an {@link MvcTestResult} is available with an
* {@linkplain MvcTestResult#getUnresolvedException() unresolved exception}
* which allows you to assert that a request failed unexpectedly:
* {@linkplain MvcTestResult#getUnresolvedException() unresolved exception}.
* Both resolved and unresolved exceptions are considered a failure that can
* be asserted as follows:
* <pre><code class="java">
* // perform a GET on /boom and assert the message for the the unresolved exception
* assertThat(mvc.get().uri("/boom")).hasUnresolvedException())
* .withMessage("Test exception");
* // perform a GET on /boom and assert the message for the the exception
* assertThat(mvc.get().uri("/boom")).hasFailed()
* .failure().hasMessage("Test exception");
* </code></pre>
*
* <p>Any attempt to access the result with an unresolved exception will
* throw an {@link AssertionError}:
* <pre><code class="java">
* // throw an AssertionError with an unresolved exception
* assertThat(mvc.get().uri("/boom")).hasStatus5xxServerError();
* </code></pre>
*
* <p>{@code MockMvcTester} can be configured with a list of

View File

@@ -59,13 +59,13 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M
}
/**
* Verify that the request failed with an unresolved exception, and
* return a new {@linkplain AbstractThrowableAssert assertion} object
* that uses the unresolved {@link Exception} as the object to test.
* Verify that the request has failed and return a new
* {@linkplain AbstractThrowableAssert assertion} object that uses the
* failure as the object to test.
*/
public AbstractThrowableAssert<?, ? extends Throwable> unresolvedException() {
hasUnresolvedException();
return Assertions.assertThat(this.actual.getUnresolvedException());
public AbstractThrowableAssert<?, ? extends Throwable> failure() {
hasFailed();
return Assertions.assertThat(getFailure());
}
/**
@@ -137,20 +137,19 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M
}
/**
* Verify that the request failed with an unresolved exception.
* @see #unresolvedException()
* Verify that the request has failed.
*/
public MvcTestResultAssert hasUnresolvedException() {
Assertions.assertThat(this.actual.getUnresolvedException())
public MvcTestResultAssert hasFailed() {
Assertions.assertThat(getFailure())
.withFailMessage("Expected request to fail, but it succeeded").isNotNull();
return this;
}
/**
* Verify that the request did not fail with an unresolved exception.
* Verify that the request has not failed.
*/
public MvcTestResultAssert doesNotHaveUnresolvedException() {
Assertions.assertThat(this.actual.getUnresolvedException())
public MvcTestResultAssert doesNotHaveFailed() {
Assertions.assertThat(getFailure())
.withFailMessage("Expected request to succeed, but it failed").isNull();
return this;
}
@@ -184,6 +183,14 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M
return this.myself;
}
@Nullable
private Throwable getFailure() {
Exception unresolvedException = this.actual.getUnresolvedException();
if (unresolvedException != null) {
return unresolvedException;
}
return this.actual.getMvcResult().getResolvedException();
}
@SuppressWarnings("NullAway")
private ModelAndView getModelAndView() {