Spring Boot集成测试返回空结果

问题描述

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

@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();
    }
}

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

@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 !!"));
      }

现在它可以正常工作了。