JUnit只会在我的类中测试那些公开的方法.如何对非(即私有,受保护)的进行junit测试?
我可以通过不使用junit来测试它们,但我想知道junit标准方法是什么.
关于单元测试的一个思想学派说,你应该只能测试公共方法,因为你应该只对你的公共API进行单元测试,并且通过这样做,你应该覆盖非公开方法中的代码.你的旅费可能会改变; 我发现有时候这种情况有时并非如此.
话虽如此,有几种方法可以测试非公开方法:
您可以通过将单元测试与他们正在测试的类放在同一个包中来测试protected和package-scope方法.这是一种相当普遍的做法.
您可以通过创建一个被测试类的子类来测试受保护的方法,从另一个包中的单元测试,该子类将要测试的方法覆盖为public,并让这些重写的方法使用super关键字调用原始方法.通常,这个"测试子类"将是执行测试的JUnit TestCase类中的内部类.在我看来,这有点多哈,但我已经做到了.
希望这可以帮助.
与许多单元测试问题一样,测试私有方法实际上是伪装的设计问题.当我发现自己希望为私人方法编写测试时,我花了一分钟时间问自己,"我怎么需要设计这个以便我可以通过公共方法彻底测试它?"而不是尝试做任何棘手的测试私有方法.
如果这不起作用,JUnitX允许测试私有方法,虽然我相信它只适用于JUnit 3.8.
当你编写一个JUnit测试时,你必须做一个微妙的思维转变:"我现在是我自己班级的客户." 这意味着私有是私有的,您只测试客户端看到的行为.
如果该方法确实应该是私有的,我认为这只是为了测试而使其可见的设计缺陷.您必须能够根据客户端看到的内容推断其正确的操作.
在我最初写这篇文章之后的三年里,我开始使用Java反射略微区别地解决问题.
肮脏的小秘密是,您可以使用反射在JUnit中测试私有方法,就像使用公共方法一样.您可以测试您的内心,但仍然不会将它们公开给客户.
最简单的解决方案是将JUnit测试放在同一个包(但不同的目录)中,并使用方法的默认(即包私有)可见性.
另一种更复杂的方法是使用反射来访问私有方法.
如果您在相对较少的"公共"入口点处埋藏了大量逻辑,那么您可能违反了单一责任原则.如果可能,您将需要将代码重构为多个类,最终导致更多"公共"方法从中进行测试.
以下是其他人一直在喋喋不休的"可能不应该这样做"的方法.不过,我认为有可能存在这样做的理由.以下代码将访问私有字段,但私有方法的代码几乎相同.
public void testPrivateField() throws InterruptedException { Classclazz = ClassWPrivateField.class; try { Field privateField = clazz.getDeclaredField("nameOfPrivateField"); privateField.setAccessible(true); // This is the line // do stuff } catch(NoSuchFieldException nsfe) { nsfe.printStackTrace(); fail(); } catch(IllegalAccessException iae) { iae.printStackTrace(); fail(); } }