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


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

    摘自http://www.tuicool.com/articles/iumaayJ

    比如说,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() 的返回值。

    所有的 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。

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

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

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

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

  • 相关阅读:
    shell awk
    spl_autoload_register array参数
    install xdebug on fedora
    call_user_func
    转载 shell sort
    通过nginx + lua来统计nginx上的监控网络请求和性能
    nginx 知识点
    python 发送带附件的 邮件
    xdebug php
    关于ZendStudio 10.5的破解
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/6189677.html
Copyright © 2020-2023  润新知