Hello!

I am testing the service for restoring requests, and it is necessary to test the rest call that they correctly deserialize the object according to a given uri. The point is, when I suspend the RestTemplate object with the @Autowired annotation, the tests pass, and when I create it using the constructor in the method itself, the tests drop.

Here is an example test:

@ContextConfiguration(classes = {RestTemplate.class, SimpleRestService.class}) public class SimpleRestServiceFunctionalTest extends AbstractJUnit4SpringContextTests { @Autowired private SimpleRestService simpleRestService; @Autowired private RestTemplate restTemplate; private MockRestServiceServer mockServer; @Before public void setUp() { mockServer = MockRestServiceServer.createServer(restTemplate); } @Test public void testGetMessage() { mockServer.expect(requestTo("https://google.com")).andExpect(method(HttpMethod.GET)) .andRespond(withSuccess("resultSuccess", MediaType.TEXT_PLAIN)); String result = simpleRestService.getMessage(); System.out.println("result: "+result); mockServer.verify(); assertThat(result, allOf(containsString("SUCCESS"), containsString("resultSuccess"))); } @Test public void testGetMessage_500() { mockServer.expect(requestTo("https://google.com")).andExpect(method(HttpMethod.GET)) .andRespond(withServerError()); String result = simpleRestService.getMessage(); System.out.println("result: "+result); mockServer.verify(); assertThat(result, allOf(containsString("FAILED"), containsString("500"))); } @Test public void testGetMessage_404() { mockServer.expect(requestTo("https://google.com")).andExpect(method(HttpMethod.GET)) .andRespond(withStatus(HttpStatus.NOT_FOUND)); String result = simpleRestService.getMessage(); System.out.println("result: "+result); mockServer.verify(); assertThat(result, allOf(containsString("FAILED"), containsString("404"))); } } 

Service example: (i.e. if resttemplate will be used here with @Autowired, then everything is fine. And if I create explicitly in the resttemplate method, then the tests will fall)

 @Service public class SimpleRestService { // @Autowired // private RestTemplate restTemplate; public String getMessage() { RestTemplate restTemplate = new RestTemplate(); String result; try { String httpResult = restTemplate.getForObject("https://google.com", String.class); result = "Message SUCCESS result: " + httpResult; } catch (HttpStatusCodeException e) { result = "Get FAILED with HttpStatusCode: " + e.getStatusCode() + "|" + e.getStatusText(); } catch (RuntimeException e) { result = "Get FAILED\n" + ExceptionUtils.getFullStackTrace(e); } return result; } } 

Question: What is the difference in these two approaches? and the second question: how to test this service for a valid message return, if you create a RestTemplate explicitly in a method?

  • Because it is Spring and there are conditions for working with the context in it, I will not go into details (there is a lot of literature for this) where there is a Bin implementation - there should not be the word new - alexandr gaiduchok

1 answer 1

The fact is that @Autowired - automatically adjusts the beans. And with your approach, you simply create a new link when this bean can have any other beans in the constructor.

You can test this bean explicitly in a method if you recognize all its dependencies of other beans and add them to the constructor. But what does @Autowired fail you to do?

  • on account of this is understandable. it is not clear why when I put an annotation on the resttemplate the tests do not fall, and when I explicitly create methods, I’m thrown out - result: Message SUCCESS result: <! doctype html> <html itemscope = "" .... That's interesting why So. - Roman
  • Message SUCCESS result - successful, right? - mrchebik
  • No, this is the message that comes first in the SimpleRestService service method getMessage () - Roman