【问题标题】:Mock internal method with JUnit and Mockito使用 JUnit 和 Mockito 模拟内部方法
【发布时间】:2014-09-28 15:58:52
【问题描述】:

我有 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 文档中检查 spy 并获得 empid 的 NullPointerException 后添加了 spying。

@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:)

【问题讨论】:

  • 阅读docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html 的第 13 和 16 章。当您阅读时,请阅读所有其他内容。
  • 谢谢!这让我想到了监视对象。所以我在我编辑的帖子中添加了间谍并得到 NullPointerException。
  • 不清楚您在哪里得到异常 - 总是发布您正在尝试修复的错误。不过,这可能与您在模拟方法中返回 null 的事实有关。
  • 是的,findEmployeeById 方法中的查询期望 empid 及其 null,我是否也需要监视 empid。我不认为我可以正确地窥探 String 对象。
  • 仍然不清楚你在哪里得到错误。 发布异常,并确定它在代码中发生的位置。

标签: java junit mockito junit4 powermock


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    -- 答案贴在下面

    我了解到我实际上不需要进行间谍活动,我也可以模拟内部方法并且有效:)

    例如,

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多