首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring MockMvc第二次测试在使用StreamingResponseBody时失败

Spring MockMvc第二次测试在使用StreamingResponseBody时失败
EN

Stack Overflow用户
提问于 2022-03-02 09:51:28
回答 2查看 371关注 0票数 1

我有一个简单的Spring服务,它使用StreamingResponseBody编写响应。在用MockMvc进行测试时,第一个测试给出了正确的响应,但第二个测试的响应体为空。然而,当我在测试中增加一点睡眠时间时,它们都能工作。

这是我的控制器(科特林)

代码语言:javascript
复制
@RestController
class DummyController() {
    @GetMapping()
    fun streamIndex() =
        ResponseEntity.ok()
            .contentType(MediaType.TEXT_PLAIN)
            .body(StreamingResponseBody { it.write("Hello world".toByteArray()) })
}

我的测试是:

代码语言:javascript
复制
@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"))
    }
}

第一次试验成功,第二次试验失败:

代码语言:javascript
复制
java.lang.AssertionError: Response content expected:<Hello world> but was:<>

然后,当我在测试中添加一个小延迟时,它会起作用:

代码语言:javascript
复制
@Test
fun test2() {
    mvc.perform(get("/")).andExpect(status().isOk)
        .andDo { Thread.sleep(5) }
        .andExpect(content().string("Hello world"))
}

这是MockMvc中的一个bug还是我测试中缺少的东西?

提前谢谢你,

抢夺

EN

回答 2

Stack Overflow用户

发布于 2022-09-12 08:23:05

不需要添加延迟,您需要首先通过以下操作获取异步结果:

代码语言:javascript
复制
@Test
fun test2() {
    mvc.perform(get("/"))
        .andExpect(request().asyncStarted())
        .andDo(MvcResult::getAsyncResult)
        .andExpect(status().isOk)
        .andExpect(content().string("Hello world"))
}

请确保将此添加到两个测试中。

资料来源:https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java @第81行

票数 1
EN

Stack Overflow用户

发布于 2022-09-12 08:32:30

你的考试错了/怪怪的。您有@SpringBootTest,它在端口上启动一个应用程序,配置了@AutoConfigureMockMvc,完全忽略了所有这些。

您的@SpringBootTest中的组合甚至不能工作,因为您不能在MockMvc中使用RANDOM_PORT (这只适用于模拟环境)。您可以使用MOCK环境或切换到TestRestTemplate/TestWebClient进行测试。

您可能已经解决了手动构造控制器和手动向该控制器注册MockMvc时遇到的问题。

最后,您使用的是异步请求,您也需要正确地使用该请求。请参阅Spring参考指南中的异步测试。它还展示了使用流响应首选的WebTestClient进行测试的另一种方法。

简而言之,你的测试有点像科学怪人的测试。

我强烈建议以适当的方式使用这些技术,并按照以下方式重写您的测试。

代码语言:javascript
复制
@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和控制器所需的内容。在测试中,异步结果现在也被正确地解析和断言。总之,它现在也应该运行得更快,因为需要启动的东西减少了(除非一开始没有太多)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71320616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档