用JUnit和Mockito模拟内部方法

时间:2014-09-28 15:58:53

标签: java junit mockito junit4 powermock

我有2个方法,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中为createEmployee方法模拟findEmployeeById(以及empid作为同一方法的输入)。

- 在检查来自Mockito文档的间谍后添加了间谍,并获取了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:)

2 个答案:

答案 0 :(得分:0)

您可以在testcase中创建新的内部类,扩展EmployeeRegistry,并覆盖方法“findEmployeeById”并调用新类的“createEmployee”。

答案 1 :(得分:0)

- 下面的答案

我了解到我实际上并不需要间谍,我也可以嘲笑内部方法并且有效:)

如,

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