当前位置:  开发笔记 > 编程语言 > 正文

junit&java:测试非公共方法

如何解决《junit&java:测试非公共方法》经验,为你挑选了6个好方法。

JUnit只会在我的类中测试那些公开的方法.如何对非(即私有,受保护)的进行junit测试?

我可以通过不使用junit来测试它们,但我想知道junit标准方法是什么.



1> MattK..:

关于单元测试的一个思想学派说,你应该只能测试公共方法,因为你应该只对你的公共API进行单元测试,并且通过这样做,你应该覆盖非公开方法中的代码.你的旅费可能会改变; 我发现有时候这种情况有时并非如此.

话虽如此,有几种方法可以测试非公开方法:

您可以通过将单元测试与他们正在测试的类放在同一个包中来测试protected和package-scope方法.这是一种相当普遍的做法.

您可以通过创建一个被测试类的子类来测试受保护的方法,从另一个包中的单元测试,该子类将要测试的方法覆盖为public,并让这些重写的方法使用super关键字调用原始方法.通常,这个"测试子类"将是执行测试的JUnit TestCase类中的内部类.在我看来,这有点多哈,但我已经做到了.

希望这可以帮助.


@Dinuk:请注意,您可以将测试和源代码放在不同的包中,而不是将测试和源代码放在不同的源代码树中.这就是Maven如何做到的(src/main/java和src/test/java).这样,实现类和测试类可以位于同一个包中,但是很容易单独处理以进行构建/部署.
实际上不需要子类化,如果你的测试类在src/box/of/Cats.java中,在你的测试项目中将测试类放到src/box/of/CatsTest.java并链接项目.这样,您的测试类似乎在同一个包中,因此可以访问彼此的受保护方法.
为了访问受保护的成员,提出了子类化方法,以符合(通常)公认的将测试和源代码放在*不同*包中的做法.这样可以轻松指定在构建自动化工具的最终分发中排除单元测试.

2> Kent Beck..:

与许多单元测试问题一样,测试私有方法实际上是伪装的设计问题.当我发现自己希望为私人方法编写测试时,我花了一分钟时间问自己,"我怎么需要设计这个以便我可以通过公共方法彻底测试它?"而不是尝试做任何棘手的测试私有方法.

如果这不起作用,JUnitX允许测试私有方法,虽然我相信它只适用于JUnit 3.8.


测试私有方法对于测试驱动的开发很有用.测试不应作为主测试系统的一部分运行(允许在不破坏构建的情况下更改实现),但它们对于指定所需行为非常有用.

3> duffymo..:

当你编写一个JUnit测试时,你必须做一个微妙的思维转变:"我现在是我自己班级的客户." 这意味着私有是私有的,您只测试客户端看到的行为.

如果该方法确实应该是私有的,我认为这只是为了测试而使其可见的设计缺陷.您必须能够根据客户端看到的内容推断其正确的操作.

在我最初写这篇文章之后的三年里,我开始使用Java反射略微区别地解决问题.

肮脏的小秘密是,您可以使用反射在JUnit中测试私有方法,就像使用公共方法一样.您可以测试您的内心,但仍然不会将它们公开给客户.



4> starblue..:

最简单的解决方案是将JUnit测试放在同一个包(但不同的目录)中,并使用方法的默认(即包私有)可见性.

另一种更复杂的方法是使用反射来访问私有方法.



5> marcumka..:

如果您在相对较少的"公共"入口点处埋藏了大量逻辑,那么您可能违反了单一责任原则.如果可能,您将需要将代码重构为多个类,最终导致更多"公共"方法从中进行测试.


这不是一个真正的答案,应该是一个评论

6> 小智..:

以下是其他人一直在喋喋不休的"可能不应该这样做"的方法.不过,我认为有可能存在这样做的理由.以下代码将访问私有字段,但私有方法的代码几乎相同.

public void testPrivateField() throws InterruptedException {
    Class clazz = 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();
    }

}

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有