How do I write a junit test for a simple controller method that returns a service method call?

Viewed 28

I am new to Spring, and also Junit testing. I would like to test this method so it increases my test line coverage.

Here is the class:

@RestController
@RequestMapping("/")
public class SummaryController {

 private final SummaryService summaryService;

 @Autowired
 public SummaryController(SummaryService summaryService) {
  this.summaryService = summaryService;
 }

 @GetMapping("/summary")
 @ResponseBody
 public List<SummaryObject> getDirectoryList() {
  return summaryService.getSummary();
 }

}


So this is a springboot/react web. application. When we click the "summary" page, we load a table with my local file directory content. summaryService.getSummary() is the method that returns a populated object model which my controller then sends the same object back to the front-end.

Here is a test I wrote to try to test this method.

@WebMvcTest (TestController.class)
public class Test Controller {
 List<SummaryObject> summaryObject;

 @Mock
 private SummaryService summaryService;


 @Test
 void testControllerMatch() {
  this.summaryObject = new ArrayList<>();
  this.summaryObject.add(new SummaryObjectModel("file name", "file size", "last modified"));
 
when(SummaryService.getSummary()).thenReturn(summaryObjectModel);

 assertEquals(SummaryObjectModel, SummaryService.getSummary());
 }
}

The test is passing, but I do not think it is testing what I want. I wanted it to test that the return statement returns the List of SummaryObjects.

I know the return statement is not tested because when I see coverage, the "return summaryService.getSummary();" line in my controller doesn't get tested (its red, not green. thus not tested).

How can I test that method indeed returns a List of SummaryObjects ?

What other kinds of tests can I write for such a simple method? How do I make that line covered in coverage ("green")?

1 Answers

Your controller code is not being covered because your test doesn't call that endpoint. To do that you might use mockMvc which apparently you were going to use. I suggest that you go through the example in the official doc.

Conceptually, your test will look like this:

@WebMvcTest
public class ControllerTest {
  @MockBean
  private SummaryService summaryService;


  @Test
  void testControllerMatch() {
    List<SummaryObject> summaries = new SummaryObject("file name", "file size", "last modified");
 
    when(summaryService.getSummary()).thenReturn(summaryObjectModel);

    // the /summary endpoint gets called here and the controller code will finally be called
    mockMvc.perform(get("/summary"))
      .andExpect(status().isOk())
      .andExpect(content().json("<JSON representation of the summary list >"));
  }
}
Related