Unnecessary Stubbing in test class when writing unit test in junit using mockito

30,640
@Test
public void persistGenericModelsAsync() throws JsonProcessingException {

    //stubbed - but never used
    when(restTemplate.exchange(Mockito.anyString(), Mockito.eq(HttpMethod.POST), Mockito.any(HttpEntity.class), Mockito.eq(JsonNode.class))).thenReturn(response);

    //stubbed - but never used
    when(response.getHeaders()).thenReturn(headers);
    List<String> cookiesTest = Arrays.asList("TxCartIdtest", "test");
    //stubbed - but never used
    when(headers.get(ValueConstant.SET_COOKIE)).thenReturn(cookiesTest);
    //stubbed - but never used
    when(response.getBody()).thenReturn(jsonNode);
}

Its clear that, none of the stubs you created with when() is getting used any where. For Eg. , the first stub where you return a response object - you have never used a call to restTemplate.exchange() any where in test execution of this method.

When you use the strict stubbing mode, you need to make sure - you use any stub that you create. See more here

Share:
30,640

Related videos on Youtube

Karan Talasila
Author by

Karan Talasila

Updated on December 25, 2021

Comments

  • Karan Talasila
    Karan Talasila over 2 years

    A method already exists as part of a module in the project. I am trying to write a test case to improve coverage. The method and it's associated class is :

    @Component
    public class GenericRestTemplate {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        CtmLogger ctmLogger;
    
        public <R, T> R persistGenericModelsAsync(T requestModel, Class<R> responseModel, String url, String postCookies)
                throws JsonProcessingException {
            ctmLogger.debugObject(ValueConstant.SHOPPING_CART_SERVICE_NAME,"REST call", url);
            HttpMethod method = HttpMethod.POST;
            Class<R> responseType = responseModel;
            ResponseEntity<JsonNode> response = null;
            HttpHeaders headers = getHeaders(postCookies);
            HttpEntity<T> requestEntity = new HttpEntity<>(requestModel, headers);
            response = restTemplate.exchange(url, method, requestEntity, JsonNode.class);
            ctmLogger.debugObject(ValueConstant.SHOPPING_CART_SERVICE_NAME,"response", response);
            List<String> cookies = response.getHeaders().get(ValueConstant.SET_COOKIE);
            ctmLogger.info("test:", cookies.toString());
            JsonNode responseBody = response.getBody();
            for (String cookie : cookies) {
                System.out.println(cookie);
                if (cookie.startsWith(((ValueConstant.TX_CART_ID)))) {
                    ((ObjectNode) responseBody).put(ValueConstant.COOKIES, cookie);
                }
            }
    
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            if ( response.getBody() != null) {
                System.out.println("entered here");
                return objectMapper.treeToValue(response.getBody(), responseType);
            }
            return (R) response.getBody();
        }
    
        private HttpHeaders getHeaders(String cartIdCookies) {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            headers.add(HttpHeaders.COOKIE, cartIdCookies);
            headers.add(HttpHeaders.HOST, "www-sit-g1.dell.com");
            return headers;
        }
    

    Now I am trying to write a test case for persistGenericModelsAsync(). The code is below:

    @RunWith(MockitoJUnitRunner.class)
    public class GenericRestTemplateTest {
    
        @InjectMocks
        GenericRestTemplate genericRestTemplate;
    
        @Mock
        RestTemplate restTemplate;
    
        @Mock
        CartRequest request;
    
        @Mock
        HttpEntity<CartRequest> requestEntity;
    
        @Mock
        ResponseEntity<JsonNode> response;
    
        @Mock
        HttpHeaders headers;
    
        @Mock
        List<String> cookies;
    
        @Mock
        JsonNode responseBody;
    
        @Mock
        ObjectMapper objectMapper;
    
        @Mock
        CartResponse cartResponse;
    
        @Mock
        CtmLogger ctmLogger;
    
        @Mock
        JsonNode jsonNode; 
    
        @Mock
        ObjectNode objectNode;
    
        @Before
        public void setup() {
            cookies = Arrays.asList("TxCartIdtest", "test");
    
        }
    
        @Test
        public void persistGenericModelsAsync() throws JsonProcessingException {
    
            when(restTemplate.exchange(Mockito.anyString(), Mockito.eq(HttpMethod.POST), Mockito.any(HttpEntity.class), Mockito.eq(JsonNode.class))).thenReturn(response);
            when(response.getHeaders()).thenReturn(headers);
            List<String> cookiesTest = Arrays.asList("TxCartIdtest", "test");
            when(headers.get(ValueConstant.SET_COOKIE)).thenReturn(cookiesTest);
            when(response.getBody()).thenReturn(jsonNode);
        }
    

    The stack trace for the error is :

    org.mockito.exceptions.misusing.UnnecessaryStubbingException:
    
    Unnecessary stubbings detected in test class: GenericRestTemplateTest
    Clean & maintainable test code requires zero unnecessary code.
    Following stubbings are unnecessary (click to navigate to relevant line of code):
      1. -> at com.dell.ctm.cart.util.GenericRestTemplateTest.persistGenericModelsAsync(GenericRestTemplateTest.java:81)
      2. -> at com.dell.ctm.cart.util.GenericRestTemplateTest.persistGenericModelsAsync(GenericRestTemplateTest.java:82)
      3. -> at com.dell.ctm.cart.util.GenericRestTemplateTest.persistGenericModelsAsync(GenericRestTemplateTest.java:84)
      4. -> at com.dell.ctm.cart.util.GenericRestTemplateTest.persistGenericModelsAsync(GenericRestTemplateTest.java:85)
    Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
    

    I am trying to mock a list of cookies and trying to see if the method is executing and covering all the statements within it. But it is throwing this Unnecessary Stubbing Exception. Where have I stubbed unnecessarily?

    • Coder
      Coder almost 5 years
      Can you post your stack trace?
    • Coder
      Coder almost 5 years
      Have you noticed that you haven't called the method you are testing in your test case? In that case all of your mock stubs are rendered unnecessary