龙和龙目岛的Mockito问题

时间:2019-08-07 11:46:42

标签: mockito powermockito

如何为下面的代码编写模仿,我经历了:https://examples.javacodegeeks.com/core-java/junit/junit-mockito-when-thenreturn-example/

代码:

@Override
public void saveEmployee(EmployeeDto dto) {
    Department department = getByDepartmentId(dto.getDepartmentId());
    RoleType roleType = getByRoleTypeId(dto.getRoleTypeId());

    Employee departmentMember = convertToEntity(dto, department, roleType);

    try {
        departmentMemberRepository.save(departmentMember);
    } catch (DataIntegrityViolationException e) {
        throw new PCDataIntegrityViolationException("error");
    } catch (Exception ex) {
        throw new InternalServerException(HttpStatus.INTERNAL_SERVER_ERROR, "error", ex);
    }
}

private Employee convertToEntity(EmployeeDto dto, Department department, RoleType roleType) {
    return Employee.pmBuilder()
            .memberEmployeeId(dto.getMemberEmployeeId())
            .memberEmployeeName(dto.getMemberEmployeeName())
            .createUser(dto.getCreateUser())
            .lastUpdateUser(dto.getLastUpdateUser())
            .status(StatusEnum.get(dto.getStatus()))
            .department(department)
            .roleType(roleType)
            .build();
}

private Department getByDepartmentId(Long departmentId) {
    Optional<Department> optDepartment = departmentRepository.findById(departmentId);
    if(!optDepartment.isPresent()) {
        throw new ResourceNotFoundException("Error");
    }
    return optDepartment.get();
}

private RoleType getByRoleTypeId(Integer roleTypeId) {
    RoleType roleType = roleTypeRepository.findByRoleTypeId(roleTypeId);
    if(roleType == null) {
        throw new ResourceNotFoundException("error");
    }
    return roleType;
}

我已经写过测试课,唯一的问题是

@RunWith(PowerMockRunner.class)
@PrepareForTest({AHUtils.class })
public class EmployeeServiceTest {
    @InjectMocks
    private EmployeeServiceimpl employeeServiceimpl;
    @Mock
    private Pageable pageable;
    @Mock
    private Page<Employee> employeePage;

    @Mock
    private EmployeeRepository employeeRepository;
    @Mock
    private DepartmentRepository departmentRepositoryMock;

    @Mock
    private Employee employee;
    @Mock
    private Optional<Employee> employeeOptional;
    @Mock
    private Department departmentMock;
    @Mock
    private Optional<Department> departmentOptionalMock;
    @Mock
    private EmployeeDto employeeDto;
    @Mock
    private Sort sortMock;
    @Mock
    private Exception ex;
    @Mock
    private Environment env;

    @Test(expected = ResourceNotFoundException.class)
    public void test_RoleTypeNotPresent() {
        when(departmentOptionalMock.get()).thenReturn(departmentMock);
        when(departmentOptionalMock.isPresent()).thenReturn(true);
        when(departmentRepositoryMock.findById(null)).thenReturn(departmentOptionalMock);
        doThrow(new ResourceNotFoundException("error")).when(employeeRepository).save(any());
        when(employeeDto.getDepartmentId()).thenReturn(null);
        employeeServiceimpl.saveEmployee(employeeDto);
    }
}

Optional<Department> optDepartment = departmentRepository.findById(departmentId);时,我想在其中具有价值,这样我就可以继续进行下去,如果阻塞了,这个测试用例就进入了。

1 个答案:

答案 0 :(得分:0)

如果您的DepartmentRepository没有注入您的EmployeeServiceimpl,请确保以下几点 (基于javadoc of InjectMocks

  • 如果您至少有一个带参数的构造函数:
    (在这种情况下,Mockito使用了构造函数注入)

    所有应该使用的模拟

    还必须注意,如果存在非无参构造函数,mockito将不考虑其他注入方法。

    / em>

  • 第二种情况是您拥有要模拟的东西的设置方法
    (在这种情况下,Mockito将使用setter注入)

  • 如果您只有一个无参数的构造函数且没有设置方法:
    (在这种情况下,Mockito将使用字段注入)

    所有带有@Mock注释的模拟必须与EmployeeServiceimpl中的字段共享相同的名称类。


Overmocking通常是指您生成了太多的模拟,即使对于不需要模拟的事物也是如此。

您可以将前三行更改为下面的示例所示。

请注意,我将.findById(null)更改为.findById(anyLong())。 我不确定getDepartmentId()实际返回的内容是什么,对于原始时间长的情况,您必须使用anyLong()作为模拟对象,默认情况下会返回0(而不是null)。

但是在下面的示例中,我将departmentId设置为1L,因此无论如何它都应该匹配。

@RunWith(PowerMockRunner.class)
@PrepareForTest({AHUtils.class })
public class EmployeeServiceTest {

    @InjectMocks
    private EmployeeServiceimpl employeeServiceimpl;

    @Mock
    private DepartmentRepository departmentRepositoryMock;

    @Test(expected = ResourceNotFoundException.class)
    public void test_RoleTypeNotPresent() {

        Department department = new Department();
        department.setDepartmentId(1L);

        // only if you can't simply create that object, use the mock
        // Department department = Mockito.mock(Department.class);

        when(departmentRepositoryMock.findById(anyLong())).thenReturn(Optional.of(department));

        // ... the rest of the example does not match with the code you posted ...

        employeeServiceimpl.saveEmployee(employeeDto);
    }
}

请注意,测试的其余部分

doThrow(new ResourceNotFoundException("error")).when(employeeRepository).save(any());
when(employeeDto.getDepartmentId()).thenReturn(null);

与您发布的代码不完全匹配。 相反,您应该在roleTypeRepository的模拟中定义一些行为。

我也不知道应该在什么时候抛出异常,因为似乎没有与employeeRepository进行任何交互。