【问题标题】:How to mock a method call in JUnit when the method is inside a base class and the testing method class extends it?当方法在基类中并且测试方法类扩展它时,如何在 JUnit 中模拟方法调用?
【发布时间】:2019-05-26 06:13:30
【问题描述】:

我需要在 JUnit 中为一个方法编写单元测试,该方法在 A 类内部,A 类扩展 B 类。我的测试方法 methodA() 调用了 B 类内部的另一个方法 B()。那么我应该如何模拟这个methodB()调用,以便当我从我的testCase调用methodA()时,当它调用methodB()时,它会获取模拟值并通过测试用例? 我应该模拟哪个类,A 类还是 B 类?

    ///logDaoImpl class extends BaseDaoImpl
    @Override
    public List<Log> LogAll(long fromIndex,long toIndex) {
    String query = "from Log ";
    QueryCondition qd = new QueryCondition();   
    qd.setIgnoreCount(false);
    qd.addAndCondition("id", ">=" , "long", fromIndex);
    List<Log> result = findByCustomNamedQuery(query, qd);   //findByCustomNamedQuery method is from my extended class 

   return result;
}

    public class BaseDaoImpl extends JpaDaoSupport implements BaseDao {

@PersistenceContext
EntityManager entityManager;


public List findByCustomNamedQuery(String query, QueryCondition qd) {

    if (qd.hasConditions()) {
        query += qd.getCondition() + qd.getOrderBy();
    }

    EntityManager em = getJpaTemplate().getEntityManagerFactory().createEntityManager();
    Query q = em.createQuery(query);    
    String[] namedParams = StringUtils.substringsBetween(query, ":", " ");
    if (namedParams != null) {
        for (int i = 0; i < namedParams.length; i++) {
            q.setParameter(namedParams[i], qd.getParamValue(namedParams[i]));
        }
    }

    if (!qd.isIgnoreCount()) {
        q.setFirstResult(qd.start());
        q.setMaxResults(qd.count());
    }

    List result =  q.getResultList();
    em.close();
    return result;
}


//test class 
  public void testLogAll() {

  List<Log>expL=new ArrayList<Log>();
    expL.add(Log);//added sample test log object from setup method
    String query = "from Log ";
    QueryCondition qd=new QueryCondition();
    qd.setIgnoreCount(false);
    qd.addAndCondition("id", ">=" , "long", 0L);
    LogDaoImpl obj=Mockito.spy(LogDaoImpl.class);
    when(obj.findByCustomNamedQuery(query,qd)).thenReturn(expL);
    List<UnbanLog> expResult = expL;
    List<UnbanLog> result = obj.LogAll(0L, 20L);
    assertEquals(expResult, result);
}

【问题讨论】:

  • 我知道这是非常基本的事情,但我没有找到任何答案。如果你知道答案,请告诉我。
  • 我已经添加了类和方法,你现在可以看一下吗
  • 当建议的解决方案不起作用时,请在您的问题中提供minimal reproducible example,向我们展示您如何尝试使用它!
  • 你注入 entityManager 并使用自己创建的 em。如果您要使用 entityManager,您可以模拟并将其注入您的 JUnit-Test。

标签: java spring unit-testing junit mockito


【解决方案1】:

ClassA 扩展 ClassB 时,你必须 spy ClassA,所以一些方法会被模拟,其余的称为原始:

@Test
public void methodATest() {
    ClassA obj = Mockito.spy(ClassA.class);
    Mockito.when(obj.methodB()).thenReturn(6);
    Assert.assertEquals(10, obj.methodA());

}

【讨论】:

  • 我认为这是正确的答案。不知道为什么它被否决了,尤其是没有任何评论。
  • 我已经用示例代码更新了问题,请现在再次检查。我尝试使用 spy 但它返回 null 异常
  • NPE 在哪里?
  • when(obj.findByCustomNamedQuery(query,qd)).thenReturn(expL); 尝试用any mockk,不知道QueryCondition 是否覆盖了hash 和equals...
  • 我在这里发布问题之前尝试了这个。不幸的是,这对我不起作用。
猜你喜欢
  • 2021-02-07
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多