3

I made a test that checked whether a post method from my controller does what it's supposed to. It worked great! Now I'm supposed to make a test to see whether the right message pops up when I get an 400 error for that post method.

Here's what I've got:

public void shouldReturnBadRequestExceptionWhenGivenBadArguments() throws Exception {
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);

    mvc.perform(post("/users")
            .contentType(MediaType.APPLICATION_JSON)
            .content(json))
            .andExpect(status().isBadRequest())
            .andExpect(result -> assertEquals("Email is already taken!", Objects.requireNonNull(result.getResolvedException()).getMessage()))
//            .andExpect(result -> assertTrue(result.getResolvedException() instanceof BadRequestException));
}

The test gives me an error as such: Status expected:<400> but was:<200>. Now I do understand that it just means I didn't get an error and instead the post method worked. Now the thing I don't know how to do is to get that error on purpose. Anyone know how to do this?

EDIT: was told to post the controller endpoint so here it is:

@PostMapping
public UserDTO addUser(@RequestBody CreateUserDTO newUser) {
    log.info(newUser.toString());
    return userService.createUser(newUser);
}

and my user was created in my setUp() (with @BeforeEach annotation) as such:

@BeforeEach
public void setUp() throws Exception {
    user = new User(
            "ime",
            "prezime",
            "imeprezime@consulteer.com",
            "1234");
}

Hope this helps!

EDIT 2: added a part of service class concerning the post method:

@Override
public UserDTO createUser(CreateUserDTO newUser) {
        if(userRepository.findByEmail(newUser.getEmail()).isPresent())
            throw new BadRequestException("Email is already taken!");

        return userMapper.convertEntityToDTO(userRepository.save(userMapper.convertCreateDTOToEntity(newUser)));

}
pantank14
  • 175
  • 1
  • 10
  • Can you please share the corresponding controller endpoint and how the `user` object inside your test is created? Otherwise it's hard to tell what's going wrong here – rieckpil Dec 17 '21 at 07:08
  • @rieckpil have added as you've asked (hopefully) – pantank14 Dec 17 '21 at 08:03
  • From what do you expect the 400 result code? Do you expect it from bean validation? Or is something inside `createUser` throwing an exception? Please also add your entire test class to understand how your test setup looks like. – rieckpil Dec 17 '21 at 09:57
  • @rieckpil Excuse my lack of knowledge about exceptions and testing, but I expect the 400 error to result from already having such a user that I'm trying to add. The only other setup I've done before what I've show is autowiring MockMvc mvc and UserServiceImpl userService. – pantank14 Dec 17 '21 at 10:05
  • I would recommend using an error 409 (conflictException), which is more explicit. Can't really see what's wrong in your code, although i'm using annotation such as Unique or Id, for this kind of things. Maybe try to debug it, and see if you're properly throwing an exception ? – Youri Dec 17 '21 at 10:16
  • please add your controller and exception advice if using – Huy Nguyen Dec 17 '21 at 10:53
  • Are you using `@SpringBootTest` or `@WebMvcTest`, what database do you use for test? To test your scenario with an integration test, you must also make sure your database already contains this user. So I'd expect two POST requests for the same user within the test – rieckpil Dec 17 '21 at 11:01
  • I'm using @WebMvcTest and the database is Postgres. I thought about making two POST requests for the same user, but when I just add .andDo() method after first, same as before happens. – pantank14 Dec 17 '21 at 11:03
  • Can you share your entire test class? Because with `@WebMvcTest` Spring Boot won't populate any database-related components and I'm wondering how your test setup looks like. – rieckpil Dec 18 '21 at 07:50

0 Answers0