Search code examples
springspring-bootjunitmockingspring-boot-test

Avoid making actual Rest call in RestTemplate Junit


Below is my EmployeeService using RestTemplate for which i have written Junit which is working .But the problem is my JUNIT is making an actual call to Rest end point.How can i avoid making an actual rest call?

@Service
public class EmployeeService {
    
    
    private RestTemplate restTemplate = new RestTemplate();

    public Employee getEmployee(String id) {
    ResponseEntity resp = 
          restTemplate.getForEntity("http://localhost:8080/employee/" + id, Employee.class);
        
    return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private EmployeeService empService = new EmployeeService();

    @Test
    public void givenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject() {
        Employee emp = new Employee(“E001”, "Eric Simmons");
        Mockito
          .when(restTemplate.getForEntity(
            “http://localhost:8080/employee/E001”, Employee.class))
          .thenReturn(new ResponseEntity(emp, HttpStatus.OK));
 
        Employee employee = empService.getEmployee(id); **// Actual call happens .How to avoid it.**
        Assert.assertEquals(emp, employee);
    }
}

Solution

  • You are creating an explicit new RestTemplate();

    So, you can not mock it.

    An approach would be creating a @Component that performs the actual call.

    @Component
    public class MyHttpClient {
    
    public ResponseEntity callingMethod(RestTemplate restTemplate, String id) {
    restTemplate.getForEntity("http://localhost:8080/employee/" + id, Employee.class);
    }
    }
    

    So, you call it from the class

    @Service
    public class EmployeeService {
    
    @Autowired
    private myHttpClient MyHttpClient;    
        
        private RestTemplate restTemplate = new RestTemplate();
    
        public Employee getEmployee(String id) {
            ResponseEntity resp = myHttpClient.callingMethod(restTemplate, id);
    ...
        }
    }
    

    From the test you mock the new class and you when it:

    @Mock
    private MyHttpClientMock myHttpClientMock;
    
    when(myHttpClientMock.callingMethod(Mockito.<RestTemplate> any()).thenReturn(HttpStatus.OK);