Currently struggling with problem when I get ‘mapping error for request’ with following controller/test configuration. Controller:
@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); } }
Test:
@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:
@Configuration public class AdtechTestConfig { @Bean public AdtechService adtechTestService() { return requestDto -> new AdtechResponseDto("123"); } }
After test execution I get No mapping for POST /subscriber/session
The reason for the struggle is that my code from other modules with the same configuration works fine. Can somebody point out what am I missing ? Thanks in advance!
Advertisement
Answer
Apparently you are loading a configuration class to mock beans, this interferes with the other parts of Spring Boot and probably leads to partially loading your application. I suspect only the mocked service is available.
Instead of the test configuration use @MockBean
to create a mock for the service and register behaviour on it.
@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 } }
If the only thing you want to test is your controller you might also want to consider using @WebMvcTest
instead of @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 } }
This will load a scaled-down version of the context (only the web parts) and will be quicker to run.