Search code examples
javaspring-bootjunitmockitoresttemplate

Getting org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch while using restTemplate


I call external API by using RestTemplate's exchange() in my application. And currently, I am writing junit and mockito test case for restTemplate call but I am getting stubbing argument mismatch exception.

Here is my code

@Service
public class ApiService {

  @Autowired
  private RestTemplate restTemplate;
  
  @Value("{url}")
  private String url;
  
  public TrackResponse getTpiValue(TrackRequest trackRequest){
  
    TrackResponse trackResponse = null;
    
    HttpHeaders headers = new HttpHeaders();
    
    HttpEntity<TrackRequest> entity = new HttpEntity<TrackRequest>(trackRequest, headers);
    
    ResponseEntity<TrackResponse> response = restTemplate.exchange(url, HttpMethod.Post, entity, TrackResponse.class);
    
    if(response.getStatusCode == HttpStatus.ok){
       trackResponse = response.getBody();
    }
  return trackResponse;
  }

}

Here is my test case

@TestInstance(Lifecycle.PER_CLASS)
@ExtendWith(MocikotExtension.class)
public class ApiServiceTest {

  @Mock
  private RestTemplate restTemplate;
  
  @InjectMocks
  private ApiService apiService;
    
  public void getTpiValueTest(){
  
    TrackRequest trackRequest = new TrackRequest();
    trackRequest.setId("UTHL10");
    
    TrackResponse trackResponse = new TrackResponse();
    trackResponse.setTrackId("QWEDRTHFDS");
    
    ResponseEntity<TrackResponse> response = new ResponseEntity<>(trackResponse, HttpStatus.ok);
    
    when(restTemplate.exchange(eq(null), eq(HttpMethod.Post), any(HttpEntity.class), eq(TrackResponse.class))).thenReturn(response);
    
    TrackResponse finalResponse = apiService.getTpiValue(trackRequest);
    
    assetEquals(response.getbody(), finalResponse.getTrackId());
  }

}

But when I run test cases then I am getting below error

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'exchange' method:
    restTemplate.exchange(
    null,
    POST,
    <com.application.track.TrackRequest@3c486eb1,[]>,
    class com.application.track.TrackResponse
);
    -> at com.application.track.ApiService.getTpiValue(ApiService.java:18)
 - has following stubbing(s) with different arguments:
    1. restTemplate.exchange(
    null,
    null,
    null,
    null
);
-> at com.application.track.ApiServiceTest.getTpiValueTest(ApiServiceTest.java:21)

I also tried with lenient() but it did not work.


Solution

  • The actual method call is :

    exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
    

    But now as you stub the first parameter as NULL , compiler does not knows its type. So it thinks you are stubbing the methods that has 4 parameters which is :

    exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType)
    

    So the actual method call is never be stubbed and it should return NULL or UnnecessaryStubbingException to me. No ideas why you get PotentialStubbingProblem though...

    Anyway try to change to the following should let you stub the actual method that ApiService will call correctly :

     when(restTemplate.exchange((String)eq(null), eq(HttpMethod.Post), any(HttpEntity.class), eq(TrackResponse.class))).thenReturn(response);
    

    or better yet :

     when(restTemplate.exchange((String)isNull(), eq(HttpMethod.Post), any(HttpEntity.class), eq(TrackResponse.class))).thenReturn(response);