Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asserting list of return items from Spring Controller with mockMvc

I've set up a spring boot application to use a Spring MVC controller to return a list of items. I have a spring test that creates a mocked dependency that gets wired in to the Controller, and the controller returns the list of expected mocked items as a JSON array.

I'm trying to assert that the content is correct simply. I want to assert that the JSON array contains the expected list. I think there's a problem trying to interpret the JSON array as a java.util.List. Is there a way to do this?

The first and second .andExpect() pass, however, the hasItems() checks do not pass. What can I do so I can just pass in my List<T> and verify it's contained in the JSON? The alternative I can think of is to conver the JSON to my List<T> and verify it using "regular java junit assertions"

public class StudentControllerTest extends AbstractControllerTest {
    @Mock
    private StudentRepository mStudentRepository;

    @InjectMocks
    private StudentController mStudentController;

    private List<Student> mStudentList;
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        setUp(mStudentController);

        // mock the student repository to provide a list of 3 students.
        mStudentList = new ArrayList<>();
        mStudentList.add(new Student("Egon Spengler", new Date(), "111-22-3333"));
        mStudentList.add(new Student("Peter Venkman", new Date(), "111-22-3334"));
        mStudentList.add(new Student("Raymond Stantz", new Date(), "111-22-3336"));
        mStudentList.add(new Student("Winston Zeddemore", new Date(), "111-22-3337"));

        when(mStudentRepository.getAllStudents()).thenReturn(mStudentList);
    }
    
    @Test
    public void listStudents() throws Exception {
        MvcResult result =
                mockMvc.perform(get("/students/list"))
                        .andDo(print())
                        .andExpect(jsonPath("$", hasSize(mStudentList.size())))
                        .andExpect(jsonPath("$.[*].name", hasItems("Peter Venkman", "Egon Spengler", "Raymond Stantz", "Winston Zeddemore")))

                        // doesn't work
                        .andExpect(jsonPath("$.[*]", hasItems(mStudentList.toArray())))
                        // doesn't work
                        .andExpect(jsonPath("$.[*]", hasItems(mStudentList.get(0))))

                        .andExpect(status().isOk())
                        .andReturn();


        String content = result.getResponse().getContentAsString();
        
    }
}
like image 628
Stealth Rabbi Avatar asked Jan 22 '17 17:01

Stealth Rabbi


1 Answers

You could try something like this:

.andExpect(MockMvcResutMatchers.content().json(convertObjectToJsonString(mStudentList)));

And you can have a method that creates JSON from a list:

 private String convertObjectToJsonString(List<Student> studentList) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(studentList);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

You can modify the convertObjectToJsonString method to accepts Student object as a parameter (if you need one specific element in response).

like image 106
Ana Avatar answered Oct 09 '22 14:10

Ana