Reputation: 33
I have below classes.
@Service
class RestService {
@Autowired
private RestTemplate restTemplate;
public ResponseEntity<String> callService(String param) {
return restTemplate.exchange(....);
}
}
@Service
class CallingService{
@Autowired
private RestService restService;
public ResponseDTO getResponse(String param) {
ResponseEntity<String> response = restService.callService(param);
ResponseDTO responseDTO = convert(response)// JSON Convertor here
return responseDTO;
}
}
Now I want to write test class for CallingService class.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import javax.xml.datatype.DatatypeConfigurationException;
import org.apache.cxf.helpers.IOUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.jupiter.api.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
class CallingServiceTest{
@InjectMocks
private CallingService service;
@Mock
private RestService restService;
@Test
public testGetResponse(){
ResponseDTO dto = createDummyObject();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> responseEntity = new ResponseEntity<>("response message", header,
HttpStatus.OK);
when(restService.callService(Mockito.anyString())).thenReturn(responseEntity);
// mocking converter here
dto = service.getResponse("param");
//assert conditions here onwards
}
}
The invocation at line service.getResponse("param") gives NullPointerException. On debugging I found that response received in CallingService.getResponse() is null (i.e. restService.callService(param) returned null) and hence code broken into convert() method.
I tried with a lot of code manipulations but no luck. Hope anyone might have answer for this.
Upvotes: 1
Views: 2396
Reputation: 33
I finally found a workaround by combining flavours of above two answers.
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.apache.cxf.helpers.IOUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class CallingServiceTest{
@InjectMocks
private CallingService service;
@Mock
private RestService restService;
@BeforeEach
public void setup(){
MockitoAnnotations.init(this);
}
@Test
public testGetResponse(){
ResponseDTO dto = createDummyObject();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> responseEntity = new ResponseEntity<> ("response message", header, HttpStatus.OK);
when(restService.callService(Mockito.anyString())).thenReturn(responseEntity);
// mocking converter here
dto = service.getResponse("param");
//assert conditions here onwards
}
}
Upvotes: 1
Reputation: 3766
Based on your import you are using a combination of Junit4
and Junit5
.
This will not work properly.
Steps to run with Junit5
org.junit.jupiter.api.*
@Before
to @BeforeEach
.@SpringBootTest
not required with Junit5
@RunWith(MockitoJUnitRunner.class)
to @ExtendWith(MockitoExtension.class)
Please find the changed code below
@ExtendWith(MockitoExtension.class)
class CallingServiceTest{
@InjectMocks
private CallingService service;
@Mock
private RestService restService;
@Test
public testGetResponse(){
ResponseDTO dto = createDummyObject();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> responseEntity = new ResponseEntity<>("response message", header,
HttpStatus.OK);
when(restService.callService(Mockito.anyString())).thenReturn(responseEntity);
// mocking converter here
dto = service.getResponse("param");
//assert conditions here onwards
}
}
If you want to run with Junit4
change your import for @Test
to import org.junit.Test
from import org.junit.jupiter.api.Test
Either one of the solutions will work.
Upvotes: 0
Reputation: 3030
You can't use both @RunWith(MockitoJUnitRunner.class)
and @SpringBootTest
. They're both setting up JUnit Rules and you can only have one rule active.
You need to use Spring annotations. Instead of @Mock
use @MockBean
so Spring can properly inject it to the service.
@SpringBootTest
class CallingServiceTest{
@Autowired
private CallingService service;
@MockBean
private RestService restService;
@Test
public testGetResponse(){
ResponseDTO dto = createDummyObject();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> responseEntity = new ResponseEntity<>("response message", header,
HttpStatus.OK);
when(restService.callService(Mockito.anyString())).thenReturn(responseEntity);
// mocking converter here
dto = service.getResponse("param");
//assert conditions here onwards
}
}
Alternatively, you can use just Mockito since you don't really need to initialize SpringContext for this test I think.
@RunWith(MockitoJUnitRunner.class)
class CallingServiceTest{
@InjectMocks
private CallingService service;
@Mock
private RestService restService;
@Test
public testGetResponse(){
ResponseDTO dto = createDummyObject();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> responseEntity = new ResponseEntity<>("response message", header,
HttpStatus.OK);
when(restService.callService(Mockito.anyString())).thenReturn(responseEntity);
// mocking converter here
dto = service.getResponse("param");
//assert conditions here onwards
}
}
Upvotes: 0