Issue
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
}
}
Solution
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());
}
}
Answered By - Georgii Lvov
Answer Checked By - Katrina (JavaFixing Volunteer)