我有一个简单的Spring服务,它使用StreamingResponseBody编写响应。在用MockMvc进行测试时,第一个测试给出了正确的响应,但第二个测试的响应体为空。然而,当我在测试中增加一点睡眠时间时,它们都能工作。
这是我的控制器(科特林)
@RestController
class DummyController() {
@GetMapping()
fun streamIndex() =
ResponseEntity.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(StreamingResponseBody { it.write("Hello world".toByteArray()) })
}我的测试是:
@AutoConfigureMockMvc(print = MockMvcPrint.NONE)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DummyControllerTest {
private val controller = DummyController()
private val mvc = MockMvcBuilders.standaloneSetup(controller).setControllerAdvice(GlobalExceptionHandler()).build()
@Test
fun test1() {
mvc.perform(get("/")).andExpect(status().isOk).andExpect(content().string("Hello world"))
}
@Test
fun test2() {
mvc.perform(get("/")).andExpect(status().isOk).andExpect(content().string("Hello world"))
}
}第一次试验成功,第二次试验失败:
java.lang.AssertionError: Response content expected:<Hello world> but was:<>然后,当我在测试中添加一个小延迟时,它会起作用:
@Test
fun test2() {
mvc.perform(get("/")).andExpect(status().isOk)
.andDo { Thread.sleep(5) }
.andExpect(content().string("Hello world"))
}这是MockMvc中的一个bug还是我测试中缺少的东西?
提前谢谢你,
抢夺
发布于 2022-09-12 08:23:05
不需要添加延迟,您需要首先通过以下操作获取异步结果:
@Test
fun test2() {
mvc.perform(get("/"))
.andExpect(request().asyncStarted())
.andDo(MvcResult::getAsyncResult)
.andExpect(status().isOk)
.andExpect(content().string("Hello world"))
}请确保将此添加到两个测试中。
发布于 2022-09-12 08:32:30
你的考试错了/怪怪的。您有@SpringBootTest,它在端口上启动一个应用程序,配置了@AutoConfigureMockMvc,完全忽略了所有这些。
您的@SpringBootTest中的组合甚至不能工作,因为您不能在MockMvc中使用RANDOM_PORT (这只适用于模拟环境)。您可以使用MOCK环境或切换到TestRestTemplate/TestWebClient进行测试。
您可能已经解决了手动构造控制器和手动向该控制器注册MockMvc时遇到的问题。
最后,您使用的是异步请求,您也需要正确地使用该请求。请参阅Spring参考指南中的异步测试。它还展示了使用流响应首选的WebTestClient进行测试的另一种方法。
简而言之,你的测试有点像科学怪人的测试。
我强烈建议以适当的方式使用这些技术,并按照以下方式重写您的测试。
@WebMvcTest(DummyController.class)
class DummyControllerTest {
@Autowired
private val mvc;
@Test
fun test1() {
var mvcResult = mvc.perform(get("/"))
.andExpect(request().asyncStarted())
.andExpect(status().isOk)
.andExpect(request().asyncResult("Hello world"))
}
@Test
fun test2() {
mvc.perform(get("/"))
.andExpect(request().asyncStarted())
.andExpect(status().isOk)
.andExpect(request().asyncResult("Hello world"))
}
}这个测试不会启动一个完整的容器,而只会启动Web和控制器所需的内容。在测试中,异步结果现在也被正确地解析和断言。总之,它现在也应该运行得更快,因为需要启动的东西减少了(除非一开始没有太多)。
https://stackoverflow.com/questions/71320616
复制相似问题