Mock a method coming from parent class to return a mocked data

Viewed 378

I have a method coming from another class which is the super class for the method I am testing. I wish to mock it such that when I reach that method, I just want to return a mocked data.

But currently, it keeps going into the method instead of skipping it and just assigning the mock data.

Could I please get some help on why my mocking is not working?

Please note that the parent class is actually coming from another dependency which we do not maintain and it's accessibility is protected.

Thus can't refactor the method being mocked and not looking to refactor the code. Just want to mock it.

Looking to achieve this either via mockito or powermock or combined if it comes to that. Thanks. ## Heading ##

This is the class and method being tested.

@Service
public class OfferService extends ParentClass { 

  // many other methods 

  public Object get() {
    // getHttpEntity() comes from ParentClass
    HttpEntity<Object> httpEntity = getHttpEntity("www.example.com"); // looking to mock this getHttpEntity method. I do not want to enter it. 

    // will not reach here. Failed at above line cos didn't mock getHttpEntity. 
    ResponseEntity<OfferResponses> responseEntity = restTemplate.exchange(endPoint, HttpMethod.GET, httpEntity, OfferResponses.class);
    return responseEntity.getBody();
  }

}

My Test which currently fails cos it keeps entering the getHttpEntity method.

package com.pack;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
public class OfferServiceTest {

  @InjectMocks
  OfferService offerService;

  @Mock
  RestTemplate restTemplate;

  @Mock
  HttpEntity<Object> entity;

  @Before
  public void setup()  {
    offerService = new OfferService();
    MockitoAnnotations.initMocks(this);
  }

  // failing test 
  @Test
  public void getTest() throws Exception {
    OfferResponses offerResponses = new OfferResponses();
    ResponseEntity<OfferResponses> responseEntity = new ResponseEntity<>(offerResponses, HttpStatus.OK);

    PowerMockito.when(
            restTemplate.exchange(anyString(), Matchers.eq(HttpMethod.GET)
                    , Matchers.anyObject(),
                    Matchers.<Class<OfferResponses>>anyObject()))
            .thenReturn(responseEntity);

    OfferService spy = spy(offerService);
    doReturn(entity).when(spy, "getHttpEntity", Matchers.anyString());

    Object result = offerService.get();

    // assertions
  }
}
1 Answers

So, since you want to spy your OfferService, you must invoke your get method on this spy.

With PowerMockito:

@RunWith(PowerMockRunner.class)
public class OfferServiceTest {

    @Spy
    @InjectMocks
    private OfferService offerService = new OfferService();

    @Mock
    private RestTemplate restTemplate;

    @Mock
    private HttpEntity<Object> entity;


    @Test
    public void test() {
        PowerMockito.when(offerService, "getHttpEntity", "www.example.com")
            .thenReturn(entity);

        PowerMockito.when(restTemplate.exchange(anyString(), any(), any(), any()))
                .thenReturn(something);

        assertEquals(someObject, offerService.get());
    }
}
 

Or it can be done without PowerMockito using ReflectionTestUtils:

@ExtendWith(MockitoExtension.class)
public class OfferServiceTest {

    @Spy
    @InjectMocks
    private OfferService offerService;

    @Mock
    private RestTemplate restTemplate;

    @Mock
    private HttpEntity<Object> entity;


    @Test
    public void test() {
        when(ReflectionTestUtils.invokeMethod(offerService, "getHttpEntity", "www.example.com"))
                .thenReturn(entity);

        when(restTemplate.exchange(anyString(), any(), any(), any()))
                .thenReturn(something);

        assertEquals(someObject, offerService.get());
    }
}
Related