0

I can't understand why my when/thenReturn is not mapped to the mocked bean.

During the debug I can see that the "userDto" after the line "UserDTO userDto = userService.update(id, entity);" in the tested controller is equal to null.

Any idea what I'm doing wrong?

Test file UsersControllerTest.java :

    package com.mycomp.mymessagesys.controllers;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mycomp.mymessagesys.controller.UsersController;
import com.mycomp.mymessagesys.model.UserDTO;
import com.mycomp.mymessagesys.service.UserService;

@RunWith(SpringRunner.class)
@WebMvcTest(UsersController.class)
public class UsersControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper jacksonMapper;

    @MockBean
    private UserService userService;

    @MockBean
    private UserDTO userDto;


    private UserDTO createUser(String id, int age, String name) {
        UserDTO userEntity = new UserDTO();
        userEntity.setId(id);
        userEntity.setAge(age);
        userEntity.setName(name);
        return userEntity;
    }

    @Test
    public void testUpdate() throws Exception {
        UserDTO userEntity = createUser("666", 66, "User_6");
        when(userService.update("666", userEntity)).thenReturn(userEntity);
        this.mockMvc.perform(put(UsersController.URL + "/666").contentType(MediaType.APPLICATION_JSON)
                .content(jacksonMapper.writeValueAsString(userEntity)))
        .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
        .andExpect(status().isOk());
    }


}

Tested UsersController class:

package com.mycomp.mymessagesys.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.mycomp.mymessagesys.model.UserDTO;
import com.mycomp.mymessagesys.service.UserService;

@RestController
@RequestMapping("/api/users")
public class UsersController implements RestControllerInterface<UserDTO> {

    public static final String URL = "/api/users";

    @Autowired
    private UserService userService;

    ....     

    @Override
    @PutMapping("/{id}")
    @ResponseStatus(HttpStatus.OK)
    public UserDTO update(@PathVariable("id") String id, @RequestBody UserDTO entity) {
        UserDTO userDto = userService.update(id, entity);
        return userDto;
    }

    ....
}

Service class that mocked:

package com.mycomp.mymessagesys.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mycomp.mymessagesys.model.UserDTO;
import com.mycomp.mymessagesys.repository.UserDAO;

@Service
public class UserService {

    @Autowired
    private UserDAO userDao;

    ...

    public UserDTO update(String id, UserDTO entity) {
        UserDTO existingUser = userDao.getOne(id);
        if (existingUser != null) {
            existingUser.setName(entity.getName());
            existingUser.setAge(entity.getAge());
        }
        userDao.save(existingUser);
        return userDao.getOne(id);
    }

   ....

}

1 Answers1

1

It is not mapping because the userEntity object that you are giving as a mapping condition to mockito's when condition is not equal to the userEntity object that will be created within UsersController.update method. Though they are structurally same they are different instances.

If the actual userEntity passed does not matter to you, you can write

when(userService.update(eq("666"), any(UserDTO.class))).thenReturn(userEntity);

to make it work.

Else if you want to match exact userIdentity then define first what makes one UserDTO same as another by overriding equals and hashcode method in UserDTO and then you can use

when(userService.update(eq("666"), eq(userEntity))).thenReturn(userEntity);
Dhawal Kapil
  • 2,584
  • 18
  • 31
  • Thanks to your reminder I rechecked my UserDTO.equals() and I found a mistake that caused false failure. Great, thanks! – Danny Leviev May 15 '18 at 11:06