公开私有方法以对其进行单元测试……好主意?

主持人注意: 这里已经发布了39个答案(有些已经删除)。 你发布之前你的答案,考虑你是否能添加一些有意义的讨论。您很有可能只是重复别人已经说过的话。


我偶尔会发现自己需要在类中公开一个私有方法,只是为此编写了一些单元测试。

通常这是因为该方法包含该类中其他方法之间共享的逻辑,并且更愿意自己测试该逻辑,或者还有另一个原因是我想测试同步线程中使用的逻辑而不必担心线程问题。

其他人是否发现自己正在这样做,因为我真的不喜欢这样做?我个人认为,好处超过了公开方法的问题,而该方法实际上并没有在课堂之外提供任何服务...

更新

谢谢大家的回答,似乎引起了人们的兴趣。我认为,普遍的共识是应该通过公共API进行测试,因为这是使用类的唯一方法,我对此表示同意。我在上面提到的我在上面会做的几个案例是不常见的案例,我认为这样做的好处是值得的。

但是,我可以看到每个人都指出,它永远不会真正发生。而且,当我多考虑一下时,我认为更改代码以容纳测试是一个坏主意-毕竟,我认为测试在某种程度上是一种支持工具,并且如果可以的话,将系统更改为“支持支持工具”是公然的坏习惯。


手掌心
浏览 664回答 3
3回答

哆啦的时光机

注意:此答案最初是针对以下问题而发布的:单独进行单元测试是否是通过getter公开私有实例变量的充分理由?它已合并到此示例中,因此可能是针对此处显示的用例的一点点。一般而言,我通常都会重构“生产”代码以使其更易于测试。但是,我认为这不是一个好电话。一个好的单元测试(通常)通常不必关心类的实现细节,而只关心其可见行为。不必将内部堆栈暴露给测试,而是可以测试该类在调用first()或之后以您期望的顺序返回页面last()。例如,考虑以下伪代码:public class NavigationTest {    private Navigation nav;    @Before    public void setUp() {        // Set up nav so the order is page1->page2->page3 and        // we've moved back to page2        nav = ...;    }    @Test    public void testFirst() {        nav.first();        assertEquals("page1", nav.getPage());        nav.next();        assertEquals("page2", nav.getPage());        nav.next();        assertEquals("page3", nav.getPage());    }    @Test    public void testLast() {        nav.last();        assertEquals("page3", nav.getPage());        nav.previous();        assertEquals("page2", nav.getPage());        nav.previous();        assertEquals("page1", nav.getPage());    }}

冉冉说

就个人而言,我宁愿使用公共API进行单元测试,并且我绝对不会公开私有方法只是为了使其易于测试。如果您真的想单独测试私有方法,则可以在Java中使用Easymock / Powermock来执行此操作。您必须对此务实,并且还应该知道难以测试的原因。' 听测试 '-如果很难测试,是否告诉您有关您的设计的一些信息?您能否将这种方法的测试重构到可以通过公共api进行测试的地方并轻松覆盖?这就是迈克尔·费瑟斯(Michael Feathers)在“ 有效地使用旧版代码 ”中所说的话“许多人花费大量时间试图解决该问题……真正的答案是,如果您有测试专用方法的冲动,则该方法不应该是专用的;如果将该方法公开,麻烦您了,可能是因为它是单独职责的一部分;它应该在另一个类上。” [ 有效地使用旧法典(M. Feathers,2005年)]
打开App,查看更多内容
随时随地看视频慕课网APP