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


我偶尔发现自己需要将类中的私有方法设为public,只是为了为它编写一些单元测试。

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

其他人发现他们这样做是因为我不喜欢吗?我个人认为,公开一个方法的好处超过了它在类之外没有提供任何服务的问题……

更新

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

然而,我可以看到,每个人都指出它不应该真的发生。再仔细想想,我觉得改变你的代码来适应测试是一个坏主意——毕竟我认为测试在某种程度上是一个支持工具,而改变一个系统来“支持一个支持工具”是明显的坏做法。


当前回答

就我个人而言,我在测试私有方法时也有同样的问题,这是因为一些测试工具是有限的。 如果你的设计被有限的工具所驱动,而这些工具并不能满足你的需求,那么你需要改变的是工具而不是设计。 因为你要求使用c#,我不能提出好的测试工具,但是对于Java,有两个强大的工具:TestNG和PowerMock,并且你可以找到对应的。net平台的测试工具

其他回答

在您的更新中,您说使用公共API进行测试很好。 这里实际上有两所学校。

黑盒测试 黑盒学派认为,类应该被视为一个黑盒,没有人可以看到其中的实现。测试这一点的唯一方法是通过公共API——就像类的用户将使用它一样。 白盒测试。 白盒学派认为自然地使用关于类实现的知识,然后测试类以了解它应该工作。

在这次讨论中我真的不能支持任何一方。我只是想知道有两种不同的方法来测试一个类(或库或其他)会很有趣。

如果需要,使用反射来访问私有变量。

但实际上,您并不关心类的内部状态,您只想测试公共方法是否在您可以预期的情况下返回您所期望的内容。

我通常将这些方法保留为受保护的,并将单元测试放在相同的包中(但在另一个项目或源文件夹中),在那里它们可以访问所有受保护的方法,因为类装入器将把它们放在相同的名称空间中。

我想说这是一个坏主意,因为我不确定你是否会得到任何好处,并可能出现问题。如果你改变一个调用的契约,只是为了测试一个私有方法,你并不是在测试这个类将如何使用它,而是在创建一个你从未打算发生的人为场景。

此外,通过将方法声明为公共,在六个月的时间内(在忘记将方法公开的唯一原因是为了测试之后),您(或者如果您已经移交了项目)完全不同的人将不会使用它,从而导致潜在的意想不到的后果和/或维护噩梦。

就单元测试而言,你绝对不应该添加更多的方法;我相信你最好做一个关于你的第一个()方法的测试用例,它将在每次测试之前被调用;然后,您可以多次调用- next(), previous()和last(),以查看结果是否符合您的期望。 我猜如果你不给你的类添加更多的方法(只是为了测试的目的),你会坚持测试的“黑盒”原则;