srishti
srishti

Reputation: 33

Writing junit test case for json data

i have a method in my controller class

    @RequestMapping(value = "/getSearchData/{fdate}/{tdate}", method = RequestMethod.GET)
    public @ResponseBody List<Map<String, Object>> getSearchData(@PathVariable String fdate,
        @PathVariable String tdate) {
    System.out.println("fdate============" + fdate);
    System.out.println("tdate============" + tdate);
    String frdate = fdate.substring(2, 4) + "/" + fdate.substring(0, 2) + "/" + fdate.substring(4, 8);

    String todate = tdate.substring(2, 4) + "/" + tdate.substring(0, 2) + "/" + tdate.substring(4, 8);
    String json = null;
    List<Object[]> list = retrievePublicationService.getsearchData(frdate, todate);

    List<Map<String, Object>> activeTeamMap = new ArrayList<Map<String, Object>>();

    if (list != null) {

        for (Object[] obj : list) {
            Map<String, Object> dropDownData = new HashMap<String, Object>();
            dropDownData.put("publicationId", obj[0]);
            dropDownData.put("documentId", obj[1]);
            dropDownData.put("documentType", obj[2]);
            dropDownData.put("languageCode", obj[3]);
            dropDownData.put("processStartDate", obj[4]);
            dropDownData.put("publicationType", obj[5]);
            activeTeamMap.add(dropDownData);
            System.out.println("activeTeamMap==vbnbvn==" + activeTeamMap);
        }

    } else {

    }

    return activeTeamMap;
}

I need to write a junit test case for this method. I am new to junit so I am not sure how to proceed with this one. Any kind of help will be appreciated. :(

Upvotes: 0

Views: 14217

Answers (1)

slowy
slowy

Reputation: 225

Well, you wanna test what your method does. What does it do?

I see, it substrings some strings to get a from date and a to date. So you want to test that. How do you do that? I see, it calls retrievePublicationService. So you can make a watcher on retrievePublicationService (using Mockito), and verify, that it calls it with your substringed parameters. Pseudocode:

RetrievePublicationService retrievePublicationService = Mockito.mock(RPS.class)
String fromDate = "real from date here";
String toDate = "real to date here";
TheClassUnderTest tcut = new TheClassUnderTest(retrievePublicationService);
String substringedFromDate = "expected from date";
String substringedToDate = "expected to date";

tcut.getSearchData(fromDate, toDate);

Mockito.verify(retriebePublicationService).getSearchData(eq(substringedFromDate ), eq(substringedToDate ));

Now "pro tip": The substringing of the dates does not belong the this method, a method should only do one thing.

What else do I see... What this method does, is mainly to map that Object[] array from the publication service into a Map. So we should test, that the mapping works. Pseudocode

...
String expectedPublicationId = "expectedPublicationId";
List<Object[]> searchDataPubService = new ArrayList<>();
searchData.add(new Object[]{expectedPublicationId, and the other expectedThingies});
Mockito.when(mockedRetrievePublicationService).getSearchData(any(String.class), any(String.class)).thenReturn(searchDataPubService ); <- we tell mockito here, it should return your list, for any call.

List<Map<String, Object>> searchData = classUnderTest.getSearchData(fromDate, toDate);

assertEquals(expectedPublicationId, searchData.get(0).get("publicationId")); ... since you map the [0]th entry from the object array to they key "publicationId" in the Map
... and the other assertions

The mapping itself can be extracted to a separate method as well... so in the end your method should look something like this:

List<Map<String, Object>> getSearchData(String fdate, String tdate){
   String fromDate = parseDate(fdate);
   String toDate = parseDate(tdate);

   List<Object[]> foundData = retrievePublicationService.getSearchData(fromDate, toDate);

   return mapSearchResultToDropdown(foundData);
}

You see what I did there? I have extracted your concerns - the parsing and the mapping - so the method is much easier to read. And also much easier to test, because the mapping and parsing of the date can be tested seperately.

So what's left to test? If you'd extract parseDate into a seperate type, you could also verify, that parseDate is called once with fdate, once with tdate. You can then verify that retrievePublicationService has been called with the parsed dates. And you would have to extract the mapping method to a seperate type too, to test, that it has been called with the data, the retriebePublicationService would have returned...

Well.. sorry for the long text, hope it helps anway :P

Upvotes: 1

Related Questions