【问题标题】:Unit testing Private Functions in Junit with Mockito使用 Mockito 在 Junit 中对私有函数进行单元测试
【发布时间】:2018-12-03 16:13:47
【问题描述】:

我是 Java 和 Junit 的新手,

有人知道如何在 Junit 中为私有函数编写测试用例吗?

在 Google 进行一些研究后,我设置环境并在 Mock() 代理的帮助下为公共函数和模拟父类编写单元测试用例。

对于具有内联值参数的公共函数,我达到了我的期望并测试了正路径和负路径。

对于我遵循的私有方法

How do I test a private function or a class that has private methods, fields or inner classes?

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

对于字段:

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

代码:

public class universalConfiguration { 
   private Integer getTotalDocuments(Client client, String indexName, String indexType, QueryBuilder searchQueryBuilder) {
    SearchResponse response = client.prepareSearch()
             .setIndices(indexName)
             .setTypes(indexType)
             .setSize(0)
             .setQuery(searchQueryBuilder)
             .execute().actionGet();

     return (int) response.getHits().totalHits;
 }
}

这是我的代码我想用这个公共类测试这个私有方法,我尝试使用 getDeclaredMethod 和 setAccessible 来使用这个方法,但是我遇到了错误。

UniversalConfiguration universalConfiguration = new UniversalConfiguration();    
getTotalDocuments getTotalDocuments= universalConfiguration .
                                         getDeclaredMethod(getTotalDocuments,
                                         client,
                                         indexName,
                                         indexType, 
                                         searchQueryBuilder);           
    getTotalDocuments.setAccessible(true);

getTotalDocuments 方法无法解析为类型

如果我犯了任何错误,请纠正我。

【问题讨论】:

  • 您链接的线程中的最佳答案仍在 cmets 中,“测试私有方法的最佳方法不是直接测试它”。
  • 请阅读(并关注)Java Naming Conventions

标签: java unit-testing junit mockito


【解决方案1】:

改变你对 UnitTests 的看法:UnitTest 不测试代码,而是测试行为。它通过使用单元的公共接口(不一定,但通常是public 方法)并验证可观察行为,即返回值和/或与依赖关系的通信。

private 方法是实现细节,可能会因重构而改变,这正是我们希望我们的单元测试不改变以保证所需行为仍然存在的时候更改后存在。

【讨论】:

    【解决方案2】:

    这个问题有点偏颇。但是有两种简单的方法可以做到这一点:

    通过可见的方法测试它们。 将可见性更改为默认值。

    默认可见性将使方法能够在包级别被查看/调用(该方法不再是私有的)这是一种非常有效的方法,但是您的方法不再是私有的。

    通过另一种可见的方法进行测试将使您获得有效的测试覆盖率,尽管测试可能不太具体。

    如何最好地解决这个问题在很大程度上取决于您正在测试的代码。

    【讨论】:

    • 这不是一个糟糕的答案,并且被否决(我相信)因为它没有提供具体的技术指导。事实上,这个问题的难点不是技术部分——你可以将私有改为公共,你已经解决了那个部分。因此,此答案解决(或部分解决)问题的 hard 部分。谢谢!
    【解决方案3】:

    您的代码有问题,请将其更改为以下内容:

    Class universalConfiguration = UniversalConfiguration.class;    
    Class[] cArg = new Class[4];
    cArg[0] = Client.class;
    cArg[1] = String.class;
    cArg[2] = String.class;
    cArg[3] = QueryBuilder.class;
    Method getTotalDocuments = universalConfiguration.                                          getDeclaredMethod(getTotalDocumentCount,cArg);           
        getTotalDocuments.setAccessible(true);
    

    【讨论】:

    • 在这一行中 Class[] cArg = new Class[];我收到错误:变量必须提供维度表达式或数组初始化器,如@Aman Chhabra
    • getTotalDocumentCount 无法解析为变量,这个错误也来了
    • @VijayKrishna 更新了我的答案
    猜你喜欢
    • 2020-01-17
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 2020-12-03
    • 2017-11-22
    • 1970-01-01
    相关资源
    最近更新 更多