没有使用 mockmvc 的请求映射
No mapping for request with mockmvc
当我使用以下 controller/test 配置获得 'mapping error for request' 时,目前正在努力解决问题。
控制器:
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {
private final AdtechService adtechService;
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
log.trace("execute submitSession with {}", requestDto);
ResponseDtoresponse = adtechService.submitSession(requestDto);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@Test
public void testSubmitSession() throws Exception {
RequestDto requestDto = new RequestDto ();
requestDto.setKyivstarId("1123134");
requestDto.setMsisdn("123476345242");
requestDto.setPartnerId("112432523");
requestDto.setPartnerName("125798756");
String request = OBJECT_MAPPER.writeValueAsString(requestDto);
System.out.println("REQUEST: " + request);
String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
System.out.println("RESPONSE: " + response);
mockMvc.perform(post("/subscriber/session")
.content(MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString(response)));
}
}
配置:
@Configuration
public class AdtechTestConfig {
@Bean
public AdtechService adtechTestService() {
return requestDto -> new AdtechResponseDto("123");
}
}
测试执行后,我得到 No mapping for POST /subscriber/session
纠结的原因是我来自具有相同配置的其他模块的代码工作正常。有人可以指出我错过了什么吗?提前致谢!
试试这个:
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {
private AdtechService adtechService;
public AdtechController (AdtechService adtechService) {
this.adtechService= adtechService;
}
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
log.trace("execute submitSession with {}", requestDto);
ResponseDtoresponse = adtechService.submitSession(requestDto);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@Autowired
private AdtechService adtechService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mvc = MockMvcBuilders.standaloneSetup(new AdtechController(adtechService)).build();
}
@Test
public void testSubmitSession() throws Exception {
RequestDto requestDto = new RequestDto ();
requestDto.setKyivstarId("1123134");
requestDto.setMsisdn("123476345242");
requestDto.setPartnerId("112432523");
requestDto.setPartnerName("125798756");
String request = OBJECT_MAPPER.writeValueAsString(requestDto);
System.out.println("REQUEST: " + request);
String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
System.out.println("RESPONSE: " + response);
mockMvc.perform(post("/subscriber/session")
.content(MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString(response)));
}
}
AdtechTestConfig.class 是否将 /ad-tech 路径段引入到您的测试请求中?如果是这样,这就是您的测试尝试路径 /ad-tech/subscriber/session 而不是 /subscriber/session.
的原因
如果这实际上是正确的 uri,那么您可以像下面那样将 @RequestMapping 添加到控制器或仅添加到 post 方法本身
@Slf4j
@Validated
@RestController
@RequestMapping("/ad-tech")
@RequiredArgsConstructor
public class AdtechController {
private final AdtechService adtechService;
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
...
显然您正在加载一个配置 class 来模拟 bean,这会干扰 Spring 启动的其他部分,并可能导致部分加载您的应用程序。我怀疑只有模拟服务可用。
不使用测试配置,而是使用 @MockBean
为服务创建模拟并在其上注册行为。
@SpringBootTest
@AutoConfigureMockMvc
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@MockBean
private AdtechService mockService;
@BeforeEach
public void setUp() {
when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123"));
}
@Test
public void testSubmitSession() throws Exception {
// Your original test method
}
}
如果您唯一要测试的是您的控制器,您可能还想考虑使用 @WebMvcTest
而不是 @SpringBootTest
。
@WebMvcTest(AdTechController.class)
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@MockBean
private AdtechService mockService;
@BeforeEach
public void setUp() {
when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123"));
}
@Test
public void testSubmitSession() throws Exception {
// Your original test method
}
}
这将加载 scaled-down 版本的上下文(仅 Web 部件)并且会更快 运行。
当我使用以下 controller/test 配置获得 'mapping error for request' 时,目前正在努力解决问题。 控制器:
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {
private final AdtechService adtechService;
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
log.trace("execute submitSession with {}", requestDto);
ResponseDtoresponse = adtechService.submitSession(requestDto);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@Test
public void testSubmitSession() throws Exception {
RequestDto requestDto = new RequestDto ();
requestDto.setKyivstarId("1123134");
requestDto.setMsisdn("123476345242");
requestDto.setPartnerId("112432523");
requestDto.setPartnerName("125798756");
String request = OBJECT_MAPPER.writeValueAsString(requestDto);
System.out.println("REQUEST: " + request);
String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
System.out.println("RESPONSE: " + response);
mockMvc.perform(post("/subscriber/session")
.content(MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString(response)));
}
}
配置:
@Configuration
public class AdtechTestConfig {
@Bean
public AdtechService adtechTestService() {
return requestDto -> new AdtechResponseDto("123");
}
}
测试执行后,我得到 No mapping for POST /subscriber/session
纠结的原因是我来自具有相同配置的其他模块的代码工作正常。有人可以指出我错过了什么吗?提前致谢!
试试这个:
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {
private AdtechService adtechService;
public AdtechController (AdtechService adtechService) {
this.adtechService= adtechService;
}
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
log.trace("execute submitSession with {}", requestDto);
ResponseDtoresponse = adtechService.submitSession(requestDto);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@Autowired
private AdtechService adtechService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mvc = MockMvcBuilders.standaloneSetup(new AdtechController(adtechService)).build();
}
@Test
public void testSubmitSession() throws Exception {
RequestDto requestDto = new RequestDto ();
requestDto.setKyivstarId("1123134");
requestDto.setMsisdn("123476345242");
requestDto.setPartnerId("112432523");
requestDto.setPartnerName("125798756");
String request = OBJECT_MAPPER.writeValueAsString(requestDto);
System.out.println("REQUEST: " + request);
String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
System.out.println("RESPONSE: " + response);
mockMvc.perform(post("/subscriber/session")
.content(MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString(response)));
}
}
AdtechTestConfig.class 是否将 /ad-tech 路径段引入到您的测试请求中?如果是这样,这就是您的测试尝试路径 /ad-tech/subscriber/session 而不是 /subscriber/session.
的原因如果这实际上是正确的 uri,那么您可以像下面那样将 @RequestMapping 添加到控制器或仅添加到 post 方法本身
@Slf4j
@Validated
@RestController
@RequestMapping("/ad-tech")
@RequiredArgsConstructor
public class AdtechController {
private final AdtechService adtechService;
@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
...
显然您正在加载一个配置 class 来模拟 bean,这会干扰 Spring 启动的其他部分,并可能导致部分加载您的应用程序。我怀疑只有模拟服务可用。
不使用测试配置,而是使用 @MockBean
为服务创建模拟并在其上注册行为。
@SpringBootTest
@AutoConfigureMockMvc
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@MockBean
private AdtechService mockService;
@BeforeEach
public void setUp() {
when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123"));
}
@Test
public void testSubmitSession() throws Exception {
// Your original test method
}
}
如果您唯一要测试的是您的控制器,您可能还想考虑使用 @WebMvcTest
而不是 @SpringBootTest
。
@WebMvcTest(AdTechController.class)
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@MockBean
private AdtechService mockService;
@BeforeEach
public void setUp() {
when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123"));
}
@Test
public void testSubmitSession() throws Exception {
// Your original test method
}
}
这将加载 scaled-down 版本的上下文(仅 Web 部件)并且会更快 运行。