我尝试将我的示例项目升级到Spring 6.1.0-M4,但由于渲染Page
对象,一些测试失败。
- 它与旧的Spring 6.0.10* 工作得很好,我不确定是否需要额外的配置。
@RequiredArgsConstructor
@RestController
@RequestMapping("/posts")
@Validated
public class PostController {
private final PostRepository posts;
@GetMapping(value = "", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<Page<PostSummary>> getAll(@RequestParam(defaultValue = "") String q,
@RequestParam(defaultValue = "") String status,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
var postStatus = StringUtils.hasText(status) ? Status.valueOf(status) : null;
var data = this.posts.findAll(Specifications.findByKeyword(q, postStatus), PageRequest.of(page, size))
.map(p -> new PostSummary(p.getTitle(), p.getCreatedAt()));
return ok(data);
}
测试代码看起来像。
@SpringJUnitWebConfig(classes = {Jackson2ObjectMapperConfig.class, WebConfig.class, TestDataConfig.class})
@ActiveProfiles("test")
public class PostControllerTestWithMockMvcWebTestClient {
@Autowired
PostController ctrl;
WebTestClient rest;
@Autowired
PostRepository posts;
@BeforeEach
public void setup() {
this.rest = MockMvcWebTestClient
.bindToController(ctrl)
.dispatcherServletCustomizer(dispatcherServlet -> dispatcherServlet.setEnableLoggingRequestDetails(true))
.configureClient()
.build();
}
@Test
public void getAllPostsWillBeOk() throws Exception {
when(this.posts.findAll(isA(Specification.class), isA(Pageable.class)))
.thenReturn(new PageImpl<>(
List.of(
Post.builder().title("test").content("content of test1").build(),
Post.builder().title("test2").content("content of test2").build()
)
)
);
this.rest
.get()
.uri("/posts")
.exchange()
.expectStatus().isOk();
// .expectBody().jsonPath("$.totalElements").isEqualTo(2);
verify(this.posts, times(1)).findAll(isA(Specification.class), isA(Pageable.class));
verifyNoMoreInteractions(this.posts);
}
}
最后我得到了这样的例外。
2023-08-22 13:25:10,579 DEBUG [main] org.springframework.core.log.LogFormatUtils: Writing [Page 1 of 1 containing com.example.demo.web.PostSummary instances]
2023-08-22 13:25:10,638 WARN [main] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver: Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.UnsupportedOperationException)]
2023-08-22 13:25:10,666 DEBUG [main] org.springframework.core.log.LogFormatUtils: [4b544732] HTTP GET /posts
2023-08-22 13:25:10,676 DEBUG [main] org.springframework.core.log.LogFormatUtils: [4b544732] [21abda60] Response 500 INTERNAL_SERVER_ERROR
2023-08-22 13:25:10,745 ERROR [main] org.springframework.test.web.reactive.server.ExchangeResult: Request details for assertion failure:
> GET /posts
> WebTestClient-Request-Id: [1]
No content
< 500 INTERNAL_SERVER_ERROR Internal Server Error
< Content-Type: [application/json]
{"content":[{"title":"test","createdAt":null},{"title":"test2","createdAt":null}],"pageable":{"sort":{"empty":true,"sorted":false,"unsorted":true}}}
====================== MockMvc (Server) ===============================
MockHttpServletRequest:
HTTP Method = GET
Request URI = /posts
Parameters = {}
Headers = [WebTestClient-Request-Id:"1"]
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.example.demo.web.PostController
Method = com.example.demo.web.PostController#getAll(String, String, int, int)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotWritableException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 500
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = {"content":[{"title":"test","createdAt":null},{"title":"test2","createdAt":null}],"pageable":{"sort":{"empty":true,"sorted":false,"unsorted":true}}}
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status expected:<200 OK> but was:<500 INTERNAL_SERVER_ERROR>
Expected :200 OK
Actual :500 INTERNAL_SERVER_ERROR
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
at org.springframework.test.web.reactive.server.StatusAssertions.lambda$assertStatusAndReturn$4(StatusAssertions.java:236)
at org.springframework.test.web.reactive.server.ExchangeResult.assertWithDiagnostics(ExchangeResult.java:222)
at org.springframework.test.web.reactive.server.StatusAssertions.assertStatusAndReturn(StatusAssertions.java:236)
at org.springframework.test.web.reactive.server.StatusAssertions.isOk(StatusAssertions.java:68)
at com.example.demo.web.PostControllerTestWithMockMvcWebTestClient.getAllPostsWillBeOk(PostControllerTestWithMockMvcWebTestClient.java:63)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
示例项目代码如下:https://github.com/hantsy/spring6-sandbox/tree/master/data-jpa
1条答案
按热度按时间4dbbbstv1#
在新的Spring Data中,
new PageImpl(data)
将使用一个新的UnPaged
类来组装页面数据,而这个异常是由UnPaged.getOffset()
方法引发的。简单地说,我们可以使用一个自定义类来表示分页的结果,例如:
然后在控制器中尝试将返回的
Page<T>
转换为PaginatedResult<T>
。在测试代码中,控制器将返回如下响应体: