Java 使用JUnit和Mockito模拟内部方法

Java 使用JUnit和Mockito模拟内部方法,java,junit,mockito,junit4,powermock,Java,Junit,Mockito,Junit4,Powermock,我有两个方法,第一个是在jpa类中查找id的方法,另一个是创建记录的方法,该方法检查id是否已经存在,如果id不存在,则创建一个记录 public class EmployeeRegistry{ public Employee findEmployeeById(String empid){ List<Employee> results = new ArrayList<Employee>(); final Query query = entityMana

我有两个方法,第一个是在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);
}
}
由于createEmployee方法在内部调用findEmployeeById并将获取NullPointerException,因此如何模拟findEmployeeById和empid作为测试类EmployeeRegistryTest中createEmployee方法的同一方法的输入

-在检查Mockito文档中的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 Extendes EmployeeRegistry中创建新的内部类,并重写方法findeEmployeeById并调用新类的createEmployee。

-答案发布在下面

我了解到我实际上不需要间谍,我也可以模拟内部方法,这很有效:

e、 g


阅读本手册第13章和第16章。当你在读的时候,阅读所有其他的。谢谢!这让我想到了监视这个物体。所以我在我编辑的帖子中添加了间谍功能,并得到了NullPointerException。不清楚你在哪里得到了异常-总是发布你试图修复的错误。不过,这可能与您在模拟方法中返回null有关。是的,findEmployeeById方法中的查询需要empid及其null,我是否也需要监视empid。我不认为我能正确地发现字符串对象。仍然不清楚错误出在哪里。发布异常,并在代码中确定发生异常的位置。
@Test
public void createEmployeeReturnsNotNull() {    
    final Employee employee= new Employee();

    // when
    Employee employee= null;
    employeeResult = employeeRegistryImpl.createEmployee(employee);

    assertNotNull(employeeResult);
}
@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:)
@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");
}