Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using TestRestTemplate for Spring Integration Testing

I am learning Spring Integration testing and using org.springframework.boot.test.web.client.TestRestTemplate. My Spring Boot version is 2.0.2 and with some default configuration.

My Test class is :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {

    @Autowired
    TestRestTemplate restTemplate;      

    String userBaseUrl = "/api/user/";

    UserDto userDto;

    @Before
    public void setUp() {

        EnhancedRandom er = EnhancedRandomBuilder.aNewEnhancedRandomBuilder().collectionSizeRange(1, 1).build();

        userDto = er.nextObject(UserDto.class);     

    }

    @Test
    public void registerUser() throws Exception{

        ResponseEntity<ServiceResponse> responseEntity = restTemplate.postForEntity(userBaseUrl+"register_user", userDto, ServiceResponse.class);
        assertEquals(responseEntity.getStatusCode(), HttpStatus.OK);
    }
    }

And controller endpoint method is :

@RequestMapping(value="register_user",method = RequestMethod.POST)  
    public ResponseEntity<ServiceResponse> registerUser(@RequestHeader HttpHeaders headers, @RequestBody UserDto userDto) {

        log.info("Register user");

        try {           
            ServiceResponse serviceResponse = new ServiceResponse("Users listed successfully"); 

            serviceResponse.setData(userService.registerUser(userDto));

            return new ResponseEntity<ServiceResponse>(serviceResponse,HttpStatus.OK);

        } catch (Exception e) {
            GeneralUtil.logError(log, "Error Occurred listing users", e);
            HttpHeaders httpHeaders = ServiceResponse.generateRuntimeErrors(e);
            return new ResponseEntity<>(httpHeaders, HttpStatus.EXPECTATION_FAILED);
        }
    }

And ServiceResponse is :

public class ServiceResponse {

    private Boolean success;
    private String message;
    private Map<String, Object> params;
    private List<?> list;
    private Object data;
//getters,setters.
    }

This API endpoint works well when we test manually but doesn't work while running tests.It gives this error :

org.springframework.web.client.RestClientException: Error while extracting response for type [class com.eeposit.lattice.util.ServiceResponse] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (PushbackInputStream); line: 1, column: 2]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:991)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:974)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:725)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:466)
    at org.springframework.boot.test.web.client.TestRestTemplate.postForEntity(TestRestTemplate.java:502)
    at com.eeposit.lattice.controller.UserControllerIntegrationTest.registerUser(UserControllerIntegrationTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (PushbackInputStream); line: 1, column: 2]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:241)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100)
    ... 39 more
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.eeposit.lattice.util.ServiceResponse` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (PushbackInputStream); line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1031)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1290)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235)
    ... 41 more

I tried to solve this issue googling but cannot fix the issue.

like image 856
SudeepShakya Avatar asked Jul 04 '26 02:07

SudeepShakya


1 Answers

Your problem could be caused by that you get some error response which can't be parsed as ServiceResponse. Try to change the ResponseEntity type to String instead of the ServiceResponse type.

ResponseEntity<String> responseEntity = restTemplate.postForEntity(userBaseUrl+"register_user", userDto, String.class);
System.out.println("This is the response as a String" + responseEntity.getBody());

I believe that way you will be able to see what the call returns.

like image 104
GaborH Avatar answered Jul 06 '26 16:07

GaborH



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!