Browse Source

Use ExceptionCollector for soft assertions in MockMvc

See gh-26917
pull/27319/head
Sam Brannen 3 years ago
parent
commit
cd078eaad8
  1. 18
      spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java
  2. 62
      spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java

18
spring-test/src/main/java/org/springframework/test/web/servlet/ResultMatcher.java

@ -16,6 +16,8 @@
package org.springframework.test.web.servlet; package org.springframework.test.web.servlet;
import org.springframework.test.util.ExceptionCollector;
/** /**
* A {@code ResultMatcher} matches the result of an executed request against * A {@code ResultMatcher} matches the result of an executed request against
* some expectation. * some expectation.
@ -81,21 +83,11 @@ public interface ResultMatcher {
*/ */
static ResultMatcher matchAllSoftly(ResultMatcher... matchers) { static ResultMatcher matchAllSoftly(ResultMatcher... matchers) {
return result -> { return result -> {
String message = ""; ExceptionCollector exceptionCollector = new ExceptionCollector();
for (ResultMatcher matcher : matchers) { for (ResultMatcher matcher : matchers) {
try { exceptionCollector.execute(() -> matcher.match(result));
matcher.match(result);
}
catch (Error | Exception ex) {
if (!message.isEmpty()) {
message += System.lineSeparator();
}
message += ex.getMessage();
}
}
if (!message.isEmpty()) {
throw new AssertionError(message);
} }
exceptionCollector.assertEmpty();
}; };
} }

62
spring-test/src/test/java/org/springframework/test/web/servlet/ResultMatcherTests.java

@ -16,9 +16,9 @@
package org.springframework.test.web.servlet; package org.springframework.test.web.servlet;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatNoException;
@ -31,6 +31,8 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
*/ */
class ResultMatcherTests { class ResultMatcherTests {
private static final String EOL = "\n";
private final StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null); private final StubMvcResult stubMvcResult = new StubMvcResult(null, null, null, null, null, null, null);
@ -42,36 +44,74 @@ class ResultMatcherTests {
} }
@Test @Test
void softAssertionsWithOneFailure() { void softAssertionsWithOneAssertionError() {
String failureMessage = "failure message"; String failureMessage = "error";
ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(failureMessage)); ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(failureMessage));
assertThatExceptionOfType(AssertionError.class) assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> resultMatcher.match(stubMvcResult)) .isThrownBy(() -> resultMatcher.match(stubMvcResult))
.withMessage(failureMessage); .withMessage(failureMessage)
.withNoCause()
.satisfies(error -> assertThat(error).hasNoSuppressedExceptions());
}
@Test
void softAssertionsWithOneRuntimeException() {
String failureMessage = "exception";
ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(uncheckedExceptionMatcher(failureMessage));
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> resultMatcher.match(stubMvcResult))
.withMessage(failureMessage)
.withNoCause()
.satisfies(error -> assertThat(error).hasNoSuppressedExceptions());
}
@Test
void softAssertionsWithOneCheckedException() {
String failureMessage = "exception";
ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(checkedExceptionMatcher(failureMessage));
assertThatExceptionOfType(Exception.class)
.isThrownBy(() -> resultMatcher.match(stubMvcResult))
.withMessage(failureMessage)
.withNoCause()
.satisfies(exception -> assertThat(exception).hasNoSuppressedExceptions());
} }
@Test @Test
void softAssertionsWithTwoFailures() { void softAssertionsWithTwoFailures() {
String firstFailure = "firstFailure"; String firstFailure = "firstFailure";
String secondFailure = "secondFailure"; String secondFailure = "secondFailure";
ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(failingMatcher(firstFailure), exceptionalMatcher(secondFailure)); String thirdFailure = "thirdFailure";
ResultMatcher resultMatcher = ResultMatcher.matchAllSoftly(assertionErrorMatcher(firstFailure),
checkedExceptionMatcher(secondFailure), uncheckedExceptionMatcher(thirdFailure));
assertThatExceptionOfType(AssertionError.class) assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> resultMatcher.match(stubMvcResult)) .isThrownBy(() -> resultMatcher.match(stubMvcResult))
.withMessage(firstFailure + System.lineSeparator() + secondFailure); .withMessage("Multiple Exceptions (3):" + EOL + firstFailure + EOL + secondFailure + EOL + thirdFailure)
.satisfies(error -> assertThat(error.getSuppressed()).hasSize(3));
} }
private ResultMatcher failingMatcher(String failureMessage) { private ResultMatcher assertionErrorMatcher(String failureMessage) {
return result -> Assertions.fail(failureMessage); return result -> {
throw new AssertionError(failureMessage);
};
} }
private ResultMatcher exceptionalMatcher(String failureMessage) { private ResultMatcher uncheckedExceptionMatcher(String failureMessage) {
return result -> { return result -> {
throw new RuntimeException(failureMessage); throw new RuntimeException(failureMessage);
}; };
} }
void doNothing(MvcResult mvcResult) {} private ResultMatcher checkedExceptionMatcher(String failureMessage) {
return result -> {
throw new Exception(failureMessage);
};
}
void doNothing(MvcResult mvcResult) {
}
} }

Loading…
Cancel
Save