Provide better name for entry points

This commit renames AssertableMockMvc to MockMvcTester as the former
was too mouthful, and we are looking for a naming pattern that can be
applied consistently to test utilities that rely on AssertJ.

Rather than AssertableMvcResult, we now use MvcTestResult and it no
longer extends from MvcResult itself. That avoids having existing code
that is migrated to the new API whilst assigning the result to MvcResult
and get a bad DevXP as that doesn't bring any of the AssertJ support.

See gh-32712
This commit is contained in:
Stéphane Nicoll
2024-05-06 17:21:30 +02:00
parent 5567d14700
commit c8967de065
7 changed files with 155 additions and 192 deletions

View File

@@ -30,76 +30,47 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link DefaultAssertableMvcResult}.
* Tests for {@link DefaultMvcTestResult}.
*
* @author Stephane Nicoll
*/
class DefaultAssertableMvcResultTests {
class DefaultMvcTestResultTests {
@Test
void createWithMvcResultDelegatesToIt() {
MockHttpServletRequest request = new MockHttpServletRequest();
MvcResult mvcResult = mock(MvcResult.class);
given(mvcResult.getRequest()).willReturn(request);
DefaultAssertableMvcResult result = new DefaultAssertableMvcResult(mvcResult, null, null);
DefaultMvcTestResult result = new DefaultMvcTestResult(mvcResult, null, null);
assertThat(result.getRequest()).isSameAs(request);
verify(mvcResult).getRequest();
}
@Test
void createWithExceptionDoesNotAllowAccessToRequest() {
assertRequestHasFailed(DefaultAssertableMvcResult::getRequest);
assertRequestHasFailed(DefaultMvcTestResult::getRequest);
}
@Test
void createWithExceptionDoesNotAllowAccessToResponse() {
assertRequestHasFailed(DefaultAssertableMvcResult::getResponse);
assertRequestHasFailed(DefaultMvcTestResult::getResponse);
}
@Test
void createWithExceptionDoesNotAllowAccessToHandler() {
assertRequestHasFailed(DefaultAssertableMvcResult::getHandler);
}
@Test
void createWithExceptionDoesNotAllowAccessToInterceptors() {
assertRequestHasFailed(DefaultAssertableMvcResult::getInterceptors);
}
@Test
void createWithExceptionDoesNotAllowAccessToModelAndView() {
assertRequestHasFailed(DefaultAssertableMvcResult::getModelAndView);
}
@Test
void createWithExceptionDoesNotAllowAccessToResolvedException() {
assertRequestHasFailed(DefaultAssertableMvcResult::getResolvedException);
}
@Test
void createWithExceptionDoesNotAllowAccessToFlashMap() {
assertRequestHasFailed(DefaultAssertableMvcResult::getFlashMap);
}
@Test
void createWithExceptionDoesNotAllowAccessToAsyncResult() {
assertRequestHasFailed(DefaultAssertableMvcResult::getAsyncResult);
}
@Test
void createWithExceptionDoesNotAllowAccessToAsyncResultWithTimeToWait() {
assertRequestHasFailed(result -> result.getAsyncResult(1000));
assertRequestHasFailed(DefaultMvcTestResult::getResolvedException);
}
@Test
void createWithExceptionReturnsException() {
IllegalStateException exception = new IllegalStateException("Expected");
DefaultAssertableMvcResult result = new DefaultAssertableMvcResult(null, exception, null);
DefaultMvcTestResult result = new DefaultMvcTestResult(null, exception, null);
assertThat(result.getUnresolvedException()).isSameAs(exception);
}
private void assertRequestHasFailed(Consumer<DefaultAssertableMvcResult> action) {
DefaultAssertableMvcResult result = new DefaultAssertableMvcResult(null, new IllegalStateException("Expected"), null);
private void assertRequestHasFailed(Consumer<DefaultMvcTestResult> action) {
DefaultMvcTestResult result = new DefaultMvcTestResult(null, new IllegalStateException("Expected"), null);
assertThatIllegalStateException().isThrownBy(() -> action.accept(result))
.withMessageContaining("Request has failed with unresolved exception");
}

View File

@@ -43,7 +43,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.Person;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
@@ -69,19 +68,19 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests for {@link AssertableMockMvc}.
* Integration tests for {@link MockMvcTester}.
*
* @author Brian Clozel
* @author Stephane Nicoll
*/
@SpringJUnitConfig
@WebAppConfiguration
public class AssertableMockMvcIntegrationTests {
public class MockMvcTesterIntegrationTests {
private final AssertableMockMvc mockMvc;
private final MockMvcTester mockMvc;
AssertableMockMvcIntegrationTests(WebApplicationContext wac) {
this.mockMvc = AssertableMockMvc.from(wac);
MockMvcTesterIntegrationTests(WebApplicationContext wac) {
this.mockMvc = MockMvcTester.from(wac);
}
@Nested
@@ -126,8 +125,8 @@ public class AssertableMockMvcIntegrationTests {
assertThat(performWithCookie(cookie, get("/greet"))).cookies().hasValue("test", "value");
}
private AssertableMvcResult performWithCookie(Cookie cookie, MockHttpServletRequestBuilder request) {
AssertableMockMvc mockMvc = AssertableMockMvc.of(List.of(new TestController()), builder -> builder.addInterceptors(
private MvcTestResult performWithCookie(Cookie cookie, MockHttpServletRequestBuilder request) {
MockMvcTester mockMvc = MockMvcTester.of(List.of(new TestController()), builder -> builder.addInterceptors(
new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
@@ -257,12 +256,12 @@ public class AssertableMockMvcIntegrationTests {
@Test
void jsonContentCanLoadResourceFromClasspath() {
assertThat(perform(get("/message"))).bodyJson().isLenientlyEqualTo(
new ClassPathResource("message.json", AssertableMockMvcIntegrationTests.class));
new ClassPathResource("message.json", MockMvcTesterIntegrationTests.class));
}
@Test
void jsonContentUsingResourceLoaderClass() {
assertThat(perform(get("/message"))).bodyJson().withResourceLoadClass(AssertableMockMvcIntegrationTests.class)
assertThat(perform(get("/message"))).bodyJson().withResourceLoadClass(MockMvcTesterIntegrationTests.class)
.isLenientlyEqualTo("message.json");
}
@@ -416,8 +415,8 @@ public class AssertableMockMvcIntegrationTests {
}
private void testAssertionFailureWithUnresolvableException(Consumer<AssertableMvcResult> assertions) {
AssertableMvcResult result = perform(get("/error/1"));
private void testAssertionFailureWithUnresolvableException(Consumer<MvcTestResult> assertions) {
MvcTestResult result = perform(get("/error/1"));
assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> assertions.accept(result))
.withMessageContainingAll("Request has failed unexpectedly:",
@@ -441,7 +440,7 @@ public class AssertableMockMvcIntegrationTests {
@Test
void satisfiesAllowsAdditionalAssertions() {
assertThat(this.mockMvc.perform(get("/greet"))).satisfies(result -> {
assertThat(result).isInstanceOf(MvcResult.class);
assertThat(result).isInstanceOf(MvcTestResult.class);
assertThat(result).hasStatusOk();
});
}
@@ -467,7 +466,7 @@ public class AssertableMockMvcIntegrationTests {
}
private AssertableMvcResult perform(MockHttpServletRequestBuilder builder) {
private MvcTestResult perform(MockHttpServletRequestBuilder builder) {
return this.mockMvc.perform(builder);
}

View File

@@ -48,11 +48,11 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
/**
* Tests for {@link AssertableMockMvc}.
* Tests for {@link MockMvcTester}.
*
* @author Stephane Nicoll
*/
class AssertableMockMvcTests {
class MockMvcTesterTests {
private static final MappingJackson2HttpMessageConverter jsonHttpMessageConverter =
new MappingJackson2HttpMessageConverter(new ObjectMapper());
@@ -60,13 +60,13 @@ class AssertableMockMvcTests {
@Test
void createShouldRejectNullMockMvc() {
assertThatIllegalArgumentException().isThrownBy(() -> AssertableMockMvc.create(null));
assertThatIllegalArgumentException().isThrownBy(() -> MockMvcTester.create(null));
}
@Test
void createWithExistingWebApplicationContext() {
try (GenericWebApplicationContext wac = create(WebConfiguration.class)) {
AssertableMockMvc mockMvc = AssertableMockMvc.from(wac);
MockMvcTester mockMvc = MockMvcTester.from(wac);
assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 41");
assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 42");
}
@@ -74,7 +74,7 @@ class AssertableMockMvcTests {
@Test
void createWithControllerClassShouldInstantiateControllers() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class, CounterController.class);
MockMvcTester mockMvc = MockMvcTester.of(HelloController.class, CounterController.class);
assertThat(mockMvc.perform(get("/hello"))).hasBodyTextEqualTo("Hello World");
assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 1");
assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 2");
@@ -82,7 +82,7 @@ class AssertableMockMvcTests {
@Test
void createWithControllersShouldUseThemAsIs() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(new HelloController(),
MockMvcTester mockMvc = MockMvcTester.of(new HelloController(),
new CounterController(new AtomicInteger(41)));
assertThat(mockMvc.perform(get("/hello"))).hasBodyTextEqualTo("Hello World");
assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 42");
@@ -91,14 +91,14 @@ class AssertableMockMvcTests {
@Test
void createWithControllerAndCustomizations() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(List.of(new HelloController()), builder ->
MockMvcTester mockMvc = MockMvcTester.of(List.of(new HelloController()), builder ->
builder.defaultRequest(get("/hello").accept(MediaType.APPLICATION_JSON)).build());
assertThat(mockMvc.perform(get("/hello"))).hasStatus(HttpStatus.NOT_ACCEPTABLE);
}
@Test
void createWithControllersHasNoHttpMessageConverter() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(new HelloController());
MockMvcTester mockMvc = MockMvcTester.of(new HelloController());
AbstractJsonContentAssert<?> jsonContentAssert = assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson();
assertThatIllegalStateException()
.isThrownBy(() -> jsonContentAssert.extractingPath("$").convertTo(Message.class))
@@ -107,7 +107,7 @@ class AssertableMockMvcTests {
@Test
void createWithControllerCanConfigureHttpMessageConverters() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class)
MockMvcTester mockMvc = MockMvcTester.of(HelloController.class)
.withHttpMessageConverters(List.of(jsonHttpMessageConverter));
assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson()
.extractingPath("$").convertTo(Message.class).satisfies(message -> {
@@ -120,7 +120,7 @@ class AssertableMockMvcTests {
@SuppressWarnings("unchecked")
void withHttpMessageConverterDetectsJsonConverter() {
MappingJackson2HttpMessageConverter converter = spy(jsonHttpMessageConverter);
AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class)
MockMvcTester mockMvc = MockMvcTester.of(HelloController.class)
.withHttpMessageConverters(List.of(mock(), mock(), converter));
assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson()
.extractingPath("$").convertTo(Message.class).satisfies(message -> {
@@ -132,11 +132,11 @@ class AssertableMockMvcTests {
@Test
void performWithUnresolvedExceptionSetsException() {
AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class);
AssertableMvcResult result = mockMvc.perform(get("/error"));
MockMvcTester mockMvc = MockMvcTester.of(HelloController.class);
MvcTestResult result = mockMvc.perform(get("/error"));
assertThat(result.getUnresolvedException()).isInstanceOf(ServletException.class)
.cause().isInstanceOf(IllegalStateException.class).hasMessage("Expected");
assertThat(result).hasFieldOrPropertyWithValue("target", null);
assertThat(result).hasFieldOrPropertyWithValue("mvcResult", null);
}
private GenericWebApplicationContext create(Class<?>... classes) {