Spring 引导集成测试 returns 空结果

Spring boot intergration test returns empty result

我正在尝试对我的 webflux 控制器进行集成测试,但测试失败是因为未设置内容类型或内容为空。 控制器 class:

@RestController
@RequiredArgsConstructor
@SecurityRequirement(name = "bearerAuth")
@Log4j2
public class OnboardingController {
    private final Service service;

    @GetMapping(value = "/organizationQuotas", produces = MediaType.APPLICATION_JSON_VALUE)
    public Flux<OrganizationQuota> getOrganizationQuotas() {
        return service.getAllOrganizationQuotas();
    }
}

服务class是一个简单的通量返回服务。 测试 class:

@WebMvcTest(OnboardingController.class)
@RunWith(SpringRunner.class)
public class OnboardingControllerIT {

    @MockBean
    Service service;
    private EasyRandom easyRandom = new EasyRandom();

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(authorities = {"..."})
    @DisplayName("Should List All organization quotas when GET request to /organizationQuotas")
    public void shouldReturnOrganizationQuotas() throws Exception {
        when(service.getAllOrganizationQuotas())
                .thenReturn(Flux.fromStream(easyRandom.objects(OrganizationQuota.class, 5)));

        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/organizationQuotas").accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().isOk())
//                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.*", isA(ArrayList.class)))
                .andReturn();
    }
}

在此状态下,输出如下所示:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /organizationQuotas
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json"]
             Body = null
    Session Attrs = {SPRING_SECURITY_CONTEXT=org.springframework.security.core.context.SecurityContextImpl@d1e9b4bb: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d1e9b4bb:...}

Handler:
             Type = controller.OnboardingController
           Method = controller.OnboardingController#getOrganizationQuotas()

Async:
    Async started = true
     Async result = [OrganizationQuota{allowPaidServicePlans=true, ...}]

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

并以异常结束

No value at JSON path "$.*"
java.lang.AssertionError: No value at JSON path "$.*"
...

我有这些依赖关系

    testImplementation 'org.jeasy:easy-random-randomizers:5.0.0'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'

    testCompile 'io.projectreactor:reactor-test'

安全应该没问题。我可以看到正确的异步结果,但我的匹配器无法使用它。 内容类型也不会返回。是因为请求的异步特性吗?我怎样才能让它评估?感谢您的帮助。

我在 howToDoInJava 发现测试异步控制器是不同的:

我不得不使用 asyncDispatch 方法。形成参考页面,这里是例子:

      @Test
      public void testHelloWorldController() throws Exception 
      {
            MvcResult mvcResult = mockMvc.perform(get("/testCompletableFuture"))
                              .andExpect(request().asyncStarted())
                              .andDo(MockMvcResultHandlers.log())
                              .andReturn();
             
            mockMvc.perform(asyncDispatch(mvcResult))
                        .andExpect(status().isOk())
                        .andExpect(content().contentTypeCompatibleWith("text/plain"))
                        .andExpect(content().string("Hello World !!"));
      }

现在可以正常工作了。