好比說,Bird是咱們要測試的class,它有public, protected,以及private的方法。java
// 文件位置: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()
的返回值。dom
代碼細節請看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%29maven
全部的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的私有函數。 } }
在上面的代碼裏,因爲BirdTest
與Bird
在一個package test.sample
裏,因此Bird
全部的public
和protected
函數,對BirdTest
可見。可是,private
應該是不可調用的。測試
固然,有人會告訴你如何利用java reflection的API來讓private
method也能夠調用code
// 可有可無的parameter用 '_' 略去了 Method findASong = targetClass.getDeclaredMethod("findASong", _); findASong.setAccessible(true); return findASong.invoke(_, _);
可是,這打破了Bird
類的封裝,是很是很差的。設想,改動private
的方法的聲明會形成test failure,那麼private
就失去意義了。與protected
其實區別不大。ip
那麼應該怎麼作呢?get
不去測試private函數,好的private函數都應該是很小很簡單的,測試那調用了private函數的public和protected方法便可。it
或者,也許這個private函數其實應該被聲明稱protected。io
若是以上方法你都以爲不合適,而某一個private函數很複雜,很須要測試。那麼,根據Single Responsibility原則,這個private函數就應該被放到一個單獨的class裏面。
class BirdSongs { protected Song findASong(Integer id) { ... } protected void singASong(Song s) { ... } }
而後,對BirdSongs#findASong
進行測試。
若是您有不一樣意見,歡迎與我討論。