Shubhanshu
Shubhanshu

Reputation: 11

JUnit 5 Unit Testing Get and Post methods

I am new to spring boot and Junit testing. I am facing problem in testing Rest Api's Get and Post method. Many tutorials online guide about the use of mockMvc in JUnit testing. But are those still valid for JUnit 5.

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = RegisterRestController.class)
class RegisterRestControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private ObjectMapper objectMapper;

  @MockBean
  private RegisterUseCase registerUseCase;

  @Test
  void whenValidInput_thenReturns200() throws Exception {
    mockMvc.perform(...);
  }

}

However I read a article that you don't need to include @ExtendWith extension from SpringBoot 2.1 onwards. Since Junit 5 and spring boot both updated with lot of changes from previous version it has become difficult to analyse which code available online is correct regarding testing. I am not able to use MockMvc.perform().andExpect(status().isOk()).

mockMvc.perform(post("/forums/{forumId}/register", 42L)
    .contentType("application/json")
    .param("sendWelcomeMail", "true")
    .content(objectMapper.writeValueAsString(user)))
    .andExpect(status().isOk());

What is the correct use of testing Get and post methods. And testing Rest verbs comes under unit testing or integration testing?

Also guide me good source to check updated features of Junit 5 with Spring Boot(JUnit 5 doc is not helpful in my case).

Upvotes: 0

Views: 5834

Answers (1)

Chris
Chris

Reputation: 5623

You can use the MockMvcRequestBuilders inside your unit test. Here is an example with post.


@ExtendWith(SpringExtension.class)
@WebMvcTest(RegisterRestController.class)
@AutoConfigureMockMvc(addFilters = false) //for disabling secruity, remove if not needed
class RegisterRestControllerTest {

    @MockBean
    private MyService myService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void someTest() {
        // mock post of new User
        when(myService.createPojo(User.class)))
                .thenAnswer((Answer<User>) 
                     invocationOnMock -> invocationOnMock.getArgument(0, User.class));

        // test post request with data
        mockMvc.perform(MockMvcRequestBuilders
                .post("/forums/{forumId}/register", 42L)
                .contentType("application/json")
                .param("sendWelcomeMail", "true")
                .content(objectMapper.writeValueAsString(user)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("some name"));
    }

Similarly you can test GET, PUT and DELETE. Hope that helps you get into testing your controller.

To answer the unit vs. integration test part: In this case, you are testing a unit, the controller. The service, that handles the transaction and all other layers are mocked, eg with mockito in my example code.

For an integration test, you wouldn't use any mocks. And you would have a real database or at least a "fake one" like h2.

Upvotes: 1

Related Questions