'Spring boot with Mockito how to test method that return list of data from database
I need to write a test for a method from the service class that return a list of data from the database. And I do not know how to make it work because it keep giving this error message. At this point I do not know how to make it work.
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type ProjectService and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
verify(mock).someMethod();
verify(mock, times(10)).someMethod();
verify(mock, atLeastOnce()).someMethod();
at com.keita.task.service.ProjectServiceTest.itShouldFindAllProject(ProjectServiceTest.jav a:160)
This is the method I am trying to test in the service class
public List<Project> findAllProject(HttpServletResponse response) {
List<Project> findAll = projectRepo.findAll();
if (findAll.isEmpty()) {
throw new ProjectExceptionHandler(
HttpStatus.OK, response,"No content to load.");
}
return projectRepo.findAll();
}
UPDATE #2 This is the project service class. I have test the save method and that work find except for the BindingResult that check for input validation coming from the frontend side.
@Service
public class ProjectService {
private final ProjectRepo projectRepo;
private final TaskService taskService;
@Autowired
public ProjectService(ProjectRepo projectRepo, TaskService taskService) {
this.projectRepo = projectRepo;
this.taskService = taskService;
}
public void save(User user, Project project, BindingResult result, HttpServletResponse response) {
if (result.hasErrors()) {
throw new InvalidInput(result, response, "Invalid input fields. Make sure all required fields are valid");
}
findProjectByIdentifier(project.getIdentifier(), response);
project.setIdentifier(project.getIdentifier().toUpperCase());
project.setUser(user);
projectRepo.save(project);
}
public List<Project> findAllProject(HttpServletResponse response) {
List<Project> findAll = projectRepo.findAll();
if (findAll.isEmpty()) {
throw new ProjectExceptionHandler(
HttpStatus.OK, response,"No content to load.");
}
return findAll;
}
}
Below is the test code for the save method. The code run fine, but if there is a better way to test it, I would be love to know that too. @Test void isShouldSave() { // GIVEN PROJECT INFORMATION ZoneId defaultZoneId = ZoneId.systemDefault();
User user = new User();
Project project = new Project();
LocalDate localDate = LocalDate.of(2020, 7, 23);
Date date = Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
user.setUserID(627111L);
user.setFirstName("John");
user.setLastName("Smith");
project.setName("Cooking App");
project.setIdentifier("COOK12");
project.setDescription("Cooking app for everyone");
project.setUpdatedAt(date);
project.setEndDate(date);
project.setStartDate(date);
project.setCreatedAt(date);
// No project with identifier passed
given(projectRepo.findProjectByIdentifier(project.getIdentifier()))
.willReturn(Optional.empty());
//WHEN
//... IT SHOULD SAVE THE NEW PROJECT
underTest.save(user, project, bindingResult, httpServletResponse);
//THEN...
// IT SHOULD SAVE THE PROJECT AND CAPTURE THE SAVE VALUE
then(projectRepo).should().save(argumentCaptor.capture());
Project captorValue = argumentCaptor.getValue();
// IT SHOULD CHECK THAT THE CAPTURE REQUEST IS EQUAL TO PROJECT
assertThat(captorValue).isEqualTo(project);
}
In Project Service Test class. I have other that I have wrote test for such as save method and find by id method and those methods work except for this method
class ProjectServiceTest {
@Mock private ProjectRepo projectRepo;
@Mock private HttpServletResponse httpServletResponse;
@Mock private BindingResult bindingResult;
@Mock private TaskService taskService;
@Captor ArgumentCaptor<Project> argumentCaptor;
private ProjectService underTest;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
underTest = new ProjectService(projectRepo, taskService);
}
@Test
void itShouldFindAllProject() {
// GIVEN PROJECT INFORMATION
ZoneId defaultZoneId = ZoneId.systemDefault();
User user = new User();
Project project = new Project();
Project secondProject = new Project();
LocalDate localDate = LocalDate.of(2020, 7, 23);
Date date = Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
user.setUserID(627111L);
user.setFirstName("John");
user.setLastName("Smith");
project.setName("Residential Building");
project.setIdentifier("RB6172");
project.setDescription("Apt building");
project.setUpdatedAt(date);
project.setEndDate(date);
project.setStartDate(date);
project.setCreatedAt(date);
secondProject.setName("Finance Building Project");
secondProject.setIdentifier("FBP51");
secondProject.setDescription("Build a house for record kipping");
secondProject.setUpdatedAt(date);
secondProject.setEndDate(date);
secondProject.setStartDate(date);
secondProject.setCreatedAt(date);
List<Project> projects = new ArrayList<>();
projects.add(project);
projects.add(secondProject);
Project toBeUseForTest = projects.get(projects.size() - 1);
//WHEN
// IT SHOULD SAVE ALL PROJECT
projects.forEach(p -> underTest.save(user, p, bindingResult, httpServletResponse));
// THEN...IT SHOULD CHECK NUMBER OF PROJECT SAVE IS THE SAME AS CAR_LIST_SIZE
//...AND IT SHOULD CAPTURE THE SAVE REQUEST
verify(projectRepo, times(projects.size())).save(argumentCaptor.capture());
then(underTest).should().findAllProject(httpServletResponse);
}
}
Solution 1:[1]
This is caused because you're performing a mock operation on something that's not a mock. In this case, underTest, is an instance of the service class itself and if you want to do things like, then(underTest)... then it needs to be a mock.
I suggest that you mock out the projectRepo, not the service that's being tested. This way you can perform a verify operation that the projectRepo.findAll() was called, and have it return mocked data for you.
If you're testing out the save method, then only perform verifications on the methods are called within that method. Post the save method to get more details, as it looks like this is what you're testing here.
Something like
@Mock ProjectRepo projectRepo;
@InjectMocks
private ProjectService underTest;
and in your test case,
when(projectRepo.findAll()).thenReturn(<whatever data you expect to come back from this>);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lane.maxwell |
