问题描述
我正在尝试为我的 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 !!"));
}
现在它可以正常工作了。