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

新手上路,请多包涵

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


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

通常这是因为该方法包含在类中其他方法之间共享的逻辑,并且单独测试逻辑更整洁,或者另一个可能的原因是我想测试同步线程中使用的逻辑而不必担心线程问题.

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

更新

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

但是,我可以看到每个人都认为它永远不应该真正发生。仔细考虑一下,我认为更改代码以适应测试是个坏主意——毕竟我认为测试在某种程度上是一种支持工具,如果愿意,将系统更改为“支持支持工具”是公然的不好的做法。

原文由 jcvandan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 275
1 个回答

笔记:

此答案最初是针对以下问题发布的 :单独进行单元测试是否是通过 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());
    }
}

原文由 Mureinik 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题