您使用什么样的实践方法来使您的代码更加适合进行单元测试?
TDD -- 先编写测试,迫使您考虑可测试性并帮助编写实际需要的代码,而不是您认为可能需要的
重构成接口 -- 使得模拟更容易
如果不使用接口,则将公共方法设为虚方法--使得模拟更容易
依赖注入 -- 使得模拟更容易
更小、更具针对性的方法 -- 测试更加专注和易于编写
避免使用静态类
除非必要,否则避免使用单例
避免使用封闭类
依赖注入似乎有所帮助。
先写测试 - 这样,测试可以推动你的设计。
我知道我的言论可能会被贬低,但我还是要发表一下自己的意见 :)
虽然这里提出的建议大多数都很好,但我认为需要适当地加以节制。目标是编写更健壮、易于更改和可维护的软件。
目标不是编写可单元测试的代码。尽管编写可测试的代码很重要,但在实现目标的过程中,投入了大量的精力去实现可测试性。它听起来很好,肯定会让人感到温暖和舒服,但事实上所有这些技术、框架、测试等都有成本。
它们需要消耗时间进行培训、维护,还会增加生产力开销等等。有时值得,有时不值得,但您永远不应该带着盲目的心态,只为了使代码更具有“可测试性”而前进。
在编写测试时(与任何其他软件任务一样),不要重复自己(DRY原则)。如果您有对多个测试有用的测试数据,则将其放置在两个测试都可以使用的地方。不要将代码复制到两个测试中。我知道这似乎很明显,但我经常看到这种情况发生。
我尽可能地采用测试驱动开发,这样我就没有任何不能进行单元测试的代码。除非有了单元测试,否则它不会存在。
小而高度内聚的方法。我是通过艰难的方式学到这一点的。想象一下,您有一个处理身份验证的公共方法。也许您已经做了TDD测试,但是如果该方法很大,那么调试就会很困难。相反,如果那个#authenticate方法以更伪代码的方式执行操作,调用其他小方法(可能是受保护的方法),当出现错误时,很容易为这些小方法编写新的测试并找到有问题的方法。