我有两个方法,jpa类中的第一个方法用于查找id,另一个方法用于创建记录(检查id是否已经存在,如果id不存在,则创建一个记录)。
public class EmployeeRegistry{
public Employee findEmployeeById(String empid){
List<Employee> results = new ArrayList<Employee>();
final Query query = entityManager.createNamedQuery("employeeRegistryImpl.findByEmployeeId");
query.setParameter("empid", empid);
results = (List<Employee>) query.getResultList();
if (CollectionUtils.isEmpty(results)) {
return null;
}
return results.get(0);
}
public Employee createEmployee(final Employee employee) throws PersistenceException{
if ((findEmployeeById(employee.getId()!=null)) {
throw new EntityExistsException();
}
return entitytManager.merge(employee);
}
}
我用JUnit和Mockito框架为第一个方法findEmployeeById编写了测试用例。例如
@RunWith(MockitoJUnitRunner.class)
public class EmployeeRegistryImplTest{
private String empid = "empid";
@Mock
private static EntityManager entityManager;
@Mock
private static Query query;
@InjectMocks
private static EmployeeRegistry employeeRegistryImpl;
@Test
public void findEmployeeByIdReturnsNull() {
final List<Employee> employees = new ArrayList<Employee>();
// given
given(entityManager.createNamedQuery("employeeRegistryImpl.findByEmployeeId")).willReturn(query);
given(query.setParameter("empid", empid)).willReturn(query);
given(query.getResultList()).willReturn(employees);
// when
Employee employeeResult = null;
employeeResult = employeeRegistryImpl.findEmployeeById(empid);
// then
assertNull(employeeResult);
verify(entityManager, Mockito.times(1)).createNamedQuery
("employeeRegistryImpl.findEmployeeById");
}
我试图为createEmployee 编写测试用例
@Test
public void createEmployeeReturnsNotNull() {
final Employee employee= new Employee();
// when
Employee employee= null;
employeeResult = employeeRegistryImpl.createEmployee(employee);
assertNotNull(employeeResult);
}
由于createEmployee方法在内部调用findEmployeeById,并将获得NullPointerException,因此我如何在我的测试类EmployeeRegistryTest中模拟createEmployme方法的findEmployer ById(和empid作为同一方法的输入)。
--在从Mockito文档中检查spy后添加了spy,并获得了empid的NullPointerException。
@Test
public void createEmployeeReturnsNotNull() {
final Employee employee = new Employee();
employee.setEmpId(empid);
final Employee employee2 = new Employee();
employee2.setEmpId(empid);
EmployeeRegistryImpl spy = Mockito.spy(employeeRegistryImpl);
// when
Employee employeeResult = null;
try {
doReturn(employee2).when(spy).findEmployeeById(empid);
employeeResult = employeeRegistryImpl
.createUser(employee);
// then
verify(spy).findEmployeeById(empid);
assertNotNull(employeeResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
-- Exception after spying
java.lang.NullPointerException
at EmployeeRegistryImpl.findEmployeeById(EmployeeRegistryImpl.java:)
at EmployeeRegistryImpl.createEmployee(EmployeeRegistryImpl.java:)
at EmployeeRegistryImplTest.createEmployeeReturnsNotNull(EmployeeRegistryImplTest.java:)
您可以在testcase中创建新的内部类extendedEmployeeRegistry,并覆盖方法"findEmployeeById"并调用新类的"createEmployee"。
-答案张贴在下方
我了解到我实际上不需要间谍,我也可以模拟内部方法,这很有效:)
例如
@Test
public void createEmployeeThrowsExceptionWhenEmployeeExists() {
final Employee employee= new Employee();
employee.setEmpId(empId);
final List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add(new employee());
// given
given(entityManager.createNamedQuery("employeeRegistryImpl.findByEmployeeId")).willReturn(query);
given(query.setParameter("empId", empId)).willReturn(query);
given(query.getResultList()).willReturn(employeeList);
// when
try {
employeeRegistryImpl.createUser(employeeList);
} catch (Exception e) {
// then
e.getErrorCode());
}
// then
verify(entityManager, Mockito.times(1)).
createNamedQuery("employeeRegistryImpl.findByEmployeeId");
}