[深入JUnit] 为什么别测试private函数

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了[深入JUnit] 为什么别测试private函数脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

比如说,Bird是我们要测试的class,它有public, protected,以及private的方法。

// 文件位置:src/test/sample/Bird.java package test.sample; class Bird {   public void fly() { ... }   public void eat() { ... }   protected void singRandomly() {      final Song s = findASong(<some_random_number>);     singASong(s);   }      private Song findASong() { ... }   private void singASong() { ... } }

现在有一个BirdTest class。对这个class而言,它可见的所有函数,是Bird.class.getDeclaredMethods()的返回值。

代码细节请看
junit.internal.MethodSorter#getDeclaredMethods()
http://grepcode.com/file/repo1.maven.org/maven2/junit/junit/4.12/org/junit/internal/MethodSorter.java#MethodSorter.getDeclaredMethods%28java.lang.Class%29
以及java.lang.Class#getDeclaredMethods()
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/lang/Class.java#Class.getDeclaredMethods%28%29

所有的public, protected, private方法BirdTest都能看到。但是,看到不等于能调用

// 文件位置:tst/test/sample/BirdTest.java package test.sample; class BirdTest {   @Test   public void testFly_CaseDescription1() {     ...     bird.fly(); //当然ok,因为Bird#fly是public的   }    @Test   public void testSingRandomly_CaseDescription1() {     ...      bird.sing(); //ok,因为BirdTest也在test.sample package下面。否则是非法的。   }    @Test   public void testFindASong() {     ...     bird.findASong(); // 非法,不能调用Bird的私有函数。   } }

在上面的代码里,由于BirdTestBird在一个package test.sample里,所以Bird所有的publicprotected函数,对BirdTest可见。但是,private应该是不可调用的。

当然,有人会告诉你如何利用java reflection的API来让private method也可以调用

// 无关紧要的parameter用 '_' 略去了 Method findASong = targetClass.getDeclaredMethod("findASong", _); findASong.setAccessible(true); return findASong.invoke(_, _);

但是,这打破了Bird类的封装,是非常不好的。设想,改动private的方法的声明会造成test failure,那么private就失去意义了。与protected其实区别不大。

那么应该怎么做呢?

  • 不去测试private函数,好的private函数都应该是很小很简单的,测试那调用了private函数的public和protected方法即可。

  • 或者,也许这个private函数其实应该被声明称protected。

  • @H_126_226@

    如果以上方法你都觉得不合适,而某一个private函数很复杂,很需要测试。那么,根据Single Responsibility原则,这个private函数就应该被放到一个单独的class里面。

    class Birdsongs {   protected Song findASong(Integer id) { ... }   protected void singASong(Song s) { ... } }

    然后,对BirdSongs#findASong进行测试。

    如果您有不同意见,欢迎与我讨论。

    脚本宝典总结

    以上是脚本宝典为你收集整理的[深入JUnit] 为什么别测试private函数全部内容,希望文章能够帮你解决[深入JUnit] 为什么别测试private函数所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。