MockMvc как проверить вызов метода внутри метода
Написал небольшое приложение на Spring Boot с Spring Mvc и Spring Data JPA. Сейчас пытаюсь писать тесты к его контроллеру с MockMvc. Пишу тесты почти впервые.
Не знаю как протестировать POST метод. Нужно протестировать этот метод:
@PostMapping("/add")
public String addTask(@ModelAttribute @Valid Task task, BindingResult br, Model model
, @AuthenticationPrincipal PersonDetails pd) {
if (br.hasErrors()) return "addTask";
task.setAuthor(pd.getPerson());
return showTask(taskService.save(task).getId(), 0, model, pd);
}
Не нашел в интернете (либо не понял) как протестировать вот эту строку:
task.setAuthor(pd.getPerson());
То есть я хочу проверить, что на объекте task вызывается метод setAuthor и что передаваемый в качестве параметра объект person является именно тем аутентифицированным пользователем, который получен через @AuthenticationPrincipal. Или это избыточно?
И затем проверить, что в качестве возвращаемого значения вызывается другой метод showTask.
Пробовал Mockito.verify, но он, насколько я понял, проверяет вызов метода лишь внутри тестового метода, а не внутри того основного метода, который тестируется.
ArgumentCaptor я так понял тоже не подходит, поскольку присвоение объекта person объекту task происходит позже, чем он захватывает аргументы.
Плюс по-моему для обоих способов нужно мокать сам контроллер, но его же вроде не надо мокать, если я его и проверяю?
Тестовый класс:
@SpringBootTest
//@WebMvcTest(TaskController.class)
@ContextConfiguration(classes = EffectiveMobileApplication.class)
@WebAppConfiguration
@AutoConfigureMockMvc
@ExtendWith(MockitoExtension.class)
public class TaskControllerTest {
@Autowired
private MockMvc mockMvc;
@InjectMocks
private TaskController taskController;
@Mock
private Model model;
@Spy
private List<Person> people;
@MockBean
private TaskService taskService;
@MockBean
private PersonDetailsService personDetailsService;
@Mock
private Task newCorrectTask;
@Spy
private Task task;
private Person person;
private Comment comment;
@BeforeEach
public void init() {
MockitoAnnotations.openMocks(this);
people = new ArrayList<Person>();
person = new Person();
person.setId(5l);
person.setName("Dmitriy");
person.setPassword("randompassword");
person.setEmail("[email protected]");
task = new Task();
task.setAuthor(person);
task.setExecutor(person);
task.setId(5l);
task.setStatus(Status.PROCESSING);
task.setPriority(Priority.HIGH);
newCorrectTask = new Task();
newCorrectTask.setDescription("description");
newCorrectTask.setTitle("Random Title");
newCorrectTask.setStatus(Status.PROCESSING);
newCorrectTask.setPriority(Priority.HIGH);
}
@Test
@DisplayName("Post request at '/tasks/add' should receive new Task object")
@WithMockUser("testuser")
public void givenPostAddRequest_shouldReceiveNewObject() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/tasks/add").flashAttr("task", Matchers.any(Task.class)))
.andExpect(status().isOk());
}
}
Контроллер:
@Controller
@RequestMapping("/tasks")
public class TaskController {
private TaskService taskService;
private CommentService commentService;
private PersonDetailsService personDetailsService;
@Autowired
public TaskController(TaskService taskService, CommentService commentService
, PersonDetailsService personDetailsService) {
super();
this.taskService = taskService;
this.commentService = commentService;
this.personDetailsService = personDetailsService;
}
@PostMapping("/add")
public String addTask(@ModelAttribute @Valid Task task, BindingResult br, Model model
, @AuthenticationPrincipal PersonDetails pd) {
if (br.hasErrors()) return "addTask";
task.setAuthor(pd.getPerson());
return showTask(taskService.save(task).getId(), 0, model, pd);
}
}
Спасибо.