是否可以为单元测试更改方法可见性?

Eri*_*ric 38 c# unit-testing

很多时候,我发现自己在将方法设置为私有以防止某人在无意义的上下文中调用它(或者会破坏所涉及对象的内部状态)或将该方法设为公共(或通常是内部)之间为了将它暴露给单元测试组件.我只是想知道Stack Overflow社区对这种困境的看法是什么?

所以我想真正的问题是,关注可测试性还是保持适当的封装更好?

最近我一直倾向于可测试性,因为大多数代码只会被一小群开发人员利用,但我想我会看到其他人都在想什么?

Cha*_*les 23

不能改变客户或用户可以看到的方法的方法可见性.这样做是丑陋的,一个黑客,暴露任何愚蠢的用户可能尝试使用和爆炸你的应用程序的方法......这是你不需要的责任.

你正在使用C#是吗?查看属性类可见内部.您可以将可测试方法声明为内部方法,并允许您的单元测试程序集访问您的内部.


jri*_*sta 16

这取决于该方法是否是公共API的一部分.如果方法不属于公共API的一部分,但是从同一程序集中的其他类型公开调用,请使用internal,friend您的单元测试程序集,并对其进行单元测试.

但是,如果该方法不是/不应该是公共API的一部分,并且它不是由程序集内部的其他类型调用的,则不要直接测试它.它应该是受保护的或私有的,并且只能通过单元测试您的公共API来间接测试.如果您为类型的非公共(或应该是非公共的)成员编写单元测试,则将测试代码绑定到内部实现详细信息.

那是一个糟糕的一种耦合,增加了单元测试你所需要的数量,既能在短期内(更多的单元测试),以及在长期(更多的测试维护和修改响应重构内部实施细则)增加工作量.测试非公共成员的另一个问题是您测试可能实际上不需要或使用的代码.找到死代码的一种很好的方法是,当您的公共API被100%覆盖时,任何单元测试都不会覆盖它.删除死代码是保持代码库精益和意义的好方法,如果您不小心放入公共API中的内容以及单元测试的代码部分,则无法实现.

编辑:作为一个快速的附加说明......使用正确设计的公共API,您可以非常有效地使用Microsoft PEX之类的工具自动生成全覆盖单元测试,以测试代码的每个执行路径.结合一些涵盖关键行为的手动编写的测试,任何未涵盖的内容都可以被视为死代码并被删除,您可以大大简化您的单元测试过程.