如何在Java中为我的验证器类编写JUnit?

时间:2017-05-03 09:54:05

标签: java junit mockito

我听说Mockito框架非常适合测试目的。

任何人都可以帮助我为下面的代码编写一个好的JUnit。

@Component
public class DataIntegrityValidatorForUpdate extends EmployeeCommonValidator implements Validator {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public boolean supports(Class<?> paramClass) {
        return Employee.class.equals(paramClass);
    }

    @Override
    public void validate(Object targetObject, Errors errors) {
        if (!(targetObject instanceof Employee))
            return;

        Employee employee = (Employee) targetObject;
        Long employeeId = employee.getId();
        String tenantId = employee.getTenantId();

        // FIXME employee.getId == null or empty then throw error employee id is
        // required
        if (isEmpty(employeeId)) {
            errors.rejectValue("employee.id", "no value", "provide employee id for update");
            return;
        }

        if (!employeeRepository.checkIfEmployeeExists(employeeId, tenantId)) {
            // FIXME throw error employee id does not exist
            errors.rejectValue("employee.id", "no value present", "employee id doesn't exist");
            return;
        }

        validateEmployee(employee, errors);

        validateAssignments(employee.getAssignments(), employeeId, tenantId, errors);

    public void validateEmployee(Employee employee, Errors errors) {
        // FIXME call common validator.validateEmployee
        super.validateEmployee(employee, errors);

        // FIXME : check only for different employees

        if (checkIfColumnValueIsSameInDB("egeis_employee", "code", employee.getCode(), employee.getId(), employee.getTenantId())) {
            errors.rejectValue("employee.code", "invalid", "Employee Code cannot be changed.");
        }

        if ((employee.getPassportNo() != null) && duplicateExists("egeis_employee", "passportNo",   employee.getPassportNo(), employee.getId(), employee.getTenantId())) {
            errors.rejectValue("employee.passportNo", "concurrent", "passportNo already exists");
        }

        if ((employee.getGpfNo() != null) && duplicateExists("egeis_employee", "gpfNo", employee.getGpfNo(), employee.getId(), employee.getTenantId())) {
            errors.rejectValue("employee.gpfNo", "concurrent", "gpfNo already exists");
        }
    }


    private void validateAssignments(List<Assignment> assignments, Long employeeId, String tenantId, Errors errors) {
        validateIdsForAssignment(assignments, employeeId, tenantId, errors);

        for (int index = 0; index < assignments.size(); index++) {
            // validateDocumentsForNewAssignment(assignments.get(index),
            // errors, index);
        }
    }

    private void validateIdsForAssignment(List<Assignment> assignments, Long employeeId, String tenantId, Errors errors) {
        Map<Long, Integer> idsMap = new HashMap<>();
        for (int index = 0; index < assignments.size(); index++) {
            if (assignments.get(index).getId() != null) // FIXME check if long
                                                    // gets default value of
                                                    // 0L
                idsMap.put(assignments.get(index).getId(), index);
        }
        if (!idsMap.isEmpty())
            validateEntityId(idsMap, EntityType.ASSIGNMENT, employeeId, tenantId, errors);
    }


    public Boolean duplicateExists(String table, String column, String value, Long id, String tenantId) {
        Long idFromDb = employeeRepository.getId(table, column, value, tenantId);
        if (idFromDb == 0 || id.equals(idFromDb))
            return false;
        return true;
    }

    public Boolean checkIfColumnValueIsSameInDB(String table, String column, String value, Long id, String tenantId) {
        Long idFromDb = employeeRepository.getId(table, column, value, tenantId);
        if (id.equals(idFromDb))
            return false;
        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

鉴于您的生产代码,编写测试非常简单;像:

public class DataIntegrityValidatorForUpdateTest {

@Mock
Errors mockedErrors;
@Mock
EmployeeRepository mockedRepository;

@InjectMocks
DataIntegrityValidatorForUpdate underTest;

@Before
public void setup() {
  initMocks();
}

@Test
public void testNotAnEmployee() {
  underTest.validate("not an employee", mockedErrors);
  verifyZeroInteractions(mockedRepository, mockedErrors);
}

这是做什么的:

  • 它嘲笑你需要控制的两个对象以测试这个类
  • 它使用@InjectMocks批注来实例化您要测试的类的实例
  • 然后测试方法的一个方面 - 使用参数调用该方法,该方法应该导致方法返回并且什么都不做

以上是灵感。现在必须对其进行增强,以涵盖您的方法可以采用的所有可能路径。大多数测试方法看起来都很相似;但是你必须学习如何使用Mockito 验证来模拟对象上的某些调用进来。

但请期望我们为您做到这一点。这是您的项目,您必须学习documentationtutorials,以了解需要做什么。

除此之外:从干净的代码角度来看,我建议你重构整个事情。我宁愿抛出例外来表示验证失败;而不是使用像errors这样的输入/输出参数。