Reputation: 695
I am trying to post list of messages to the rest api. How to write mockito junit for the method postJSONData below:
public class PostDataService{
@Autowired
RestTemplate restTemplate;
@Autowired
private Environment env;
private HttpEntity<String> httpEntity;
private HttpHeaders httpHeaders;
private String resourceURL = null;
public PostDataService(){
httpHeaders = new HttpHeaders();
httpHeaders.set("Content-Type", "application/json");
}
public void postJSONData(List<String> data){
try
{
resourceURL = env.getProperty("baseURL") + env.getProperty("resourcePath");
httpEntity = new HttpEntity<String>(data.toString(), httpHeaders);
String response = restTemplate.postForObject(resourceURL, httpEntity, String.class);
}
catch (RestClientException e) {
LOGGER.info("ErrorMessage::" + e.getMessage());
LOGGER.info("ErrorCause::" + e.getCause());
}
}
}
Please help me how to write.
Upvotes: 3
Views: 22699
Reputation: 5116
Just mock postForObject
correctly:
@ExtendWith(MockitoExtension.class)
public class YourServiceTest {
@Mock
RestTemplate template;
@InjectMocks
private final YourService srv = new YourService();
@Test
public void yourTest() {
when(template.postForObject(anyString(),any(Object.class),eq(String.class)))
.thenReturn("xxxxxxxxxxx");
assertEquals("xxxxxxxxxxx", srv.yourMethod());
}
}
Upvotes: 3
Reputation: 47905
You can use Mockito to:
postData
with mocked RestTemplate
and Environment
RestTemplate
is invoked correctlyThe postJSONData
method does not use the restTemplate.postForObject()
response so the best you can do in terms of testing this method is to verify that restTemplate.postForObject()
is invoked with the correct parameters.
Here's an example:
@RunWith(MockitoJUnitRunner.class)
public class PostDataTest {
@Mock
private RestTemplate restTemplate;
@Mock
private Environment env;
@InjectMocks
private PostData postData;
@Test
public void test_postJSONData() {
String baseUrl = "theBaseUrl";
String resourcePath = "aResourcePath";
Mockito.when(env.getProperty("baseURL")).thenReturn(baseUrl);
Mockito.when(env.getProperty("resourcePath")).thenReturn(resourcePath);
List<String> payload = new ArrayList<>();
postData.postJSONData(payload);
// it's unclear from your posted code what goes into the HttpEntity so
// this approach is lenient about its expectation
Mockito.verify(restTemplate).postForObject(
Mockito.eq(baseUrl + resourcePath),
Mockito.any(HttpEntity.class),
Mockito.eq(String.class)
);
// assuming that the HttpEntity is constructed from the payload passed
// into postJSONData then this approach is more specific
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
Mockito.verify(restTemplate).postForObject(
Mockito.eq(baseUrl + resourcePath),
Mockito.eq(new HttpEntity<>(payload.toString(), headers)),
Mockito.eq(String.class)
);
}
}
On a side note; postData
is an unusual name for a class and the postJSONData
method provided in your OP doesn't compile; it references meterReadings
rather than data
.
Upvotes: 4
Reputation: 5371
You can use wiremock to mock the server. It's a mocking framework specifically for this job.
Add following dependency to your pom.xml:
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.12.0</version>
</dependency>
Add following rule to your test:
@Rule
public WireMockRule wireMockRule = new WireMockRule(); // default port is 8080
Then you should define your baseUrl
and resourcePath
properties in application.properties
(or elsewhere). Remember, the server will be running on localhost.
After that you should mock HTTP response for resourcePath:
stubFor(get(urlEqualTo(resourcePath))
.withHeader("Accept", equalTo("application/json"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(content)));
Then you can execute postJSONData method:
postData.postJSONData();
And finally, you can verify if a request to the server was correct.
verify(postRequestedFor(urlMatching(resourcePath))
.withRequestBody(matching(expectedBody))
.withHeader("Content-Type", matching("application/json")));
Upvotes: 2