I am trying to write integration test in Spring Boot 2.7.3. This application should scrape data from some external REST service. To call rest service I am using RestTemplate from spring framework
@Service
public class UserService {
private final RestTemplate restTemplate;
private String url = "http://localhost:3000/user/{name}";
@Autowired
public UserService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public UserData getUserInfo(UserInfo userInfo) {
return restTemplate.getForObject(url, UserData.class, userInfo.getName());
}
}
This service is used by rest controller that is accepting name as a path parameter (we can call it localhost:8080/info?name=joe)
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/info")
@ResponseBody
public UserData getUserData(UserInfo userInfo) {
return userService.getUserInfo(userInfo);
}
}
I have created controller annotated with @RestControllerAdvice and handling method that should be invoked when throwing HttpClientErrorException
@RestControllerAdvice
public class UserExceptionHandler {
@Autowired
public UserExceptionHandler(){
}
@ExceptionHandler(value = {HttpClientErrorException.class})
public ErrorResponse clientErrorHandle(HttpClientErrorException e) {
return ErrorResponse.builder().error("could not retrieve user info").build();
}
}
Problem is that below test is not hitting UserExceptionHandler
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
@Autowired
RestTemplate restTemplate;
@Autowired
UserController userController;
private MockRestServiceServer mockServer;
@BeforeEach
public void setUp() {
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void testGetRootResourceOnce() {
mockServer.expect(once(), requestTo("http://localhost:3000/user/joe"))
.andRespond(withBadRequest().contentType(MediaType.APPLICATION_JSON).body("{\"error\": \"Error while getting data\"}"));
UserInfo userInfo = UserInfo.builder().name("joe").build();
UserData userData = userController.getUserData(userInfo);
mockServer.verify();
assertThat(userData).isNotNull();
}
}
While debugging I set breakpoint on UserExceptionHandler constructor so I assume that it has been created.
But why method clientErrorHandle was not invoked?
I see that RestTemplate throw HttpClientErrorException (please see picture below) so it should be intercepted by my handler, but it was not
