mockito 如何测试从数据库返回数据列表的方法

1tu0hz3e  于 2022-11-08  发布在  其他
关注(0)|答案(1)|浏览(254)

我需要为服务类中的一个方法编写一个测试,该方法从数据库返回一个数据列表。我不知道如何使它工作,因为它不断给出这个错误信息。在这一点上,我不知道如何使它工作。

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)

这是我尝试在服务类中测试的方法

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这是项目服务类。我已经测试了save方法,除了BindingResult之外,它还可以查找来自前端的输入验证。

@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;
 }

}

下面是save方法的测试代码。代码运行良好,但如果有更好的方法来测试它,我也很想知道。@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);
}

在项目服务测试类中。我有其他我已经写过测试的方法,如save方法和find by id方法,除了这个方法之外,这些方法都可以工作

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);
}
}
rta7y2nd

rta7y2nd1#

这是因为你在一个非mock的东西上执行mock操作。在这个例子中,underTest,是服务类本身的一个示例,如果你想做then(underTest)...这样的事情,那么它需要是一个mock。
我建议您模拟projectRepo,而不是被测试的服务,这样您就可以执行一个verify操作,调用projectRepo.findAll(),并让它为您返回模拟的数据。
如果你要测试save方法,那么只需要验证在该方法中调用的方法。发布save方法以获得更多细节,因为看起来这就是你要测试的内容。
比如

@Mock ProjectRepo projectRepo;

@InjectMocks
private ProjectService underTest;

在您的测试用例中,

when(projectRepo.findAll()).thenReturn(<whatever data you expect to come back from this>);

相关问题