假设我有一个依赖于其他3个类X,Y和Z的A类,或者A通过引用或指针使用它们或者说A被模板化以用X实例化,Y和Z无关紧要,关键是为了测试A,我需要有X,Y和Z。
所以我需要为A,B和C制作假货。假设我写了它们。现在,我如何轻松交换真假对象?我可以看到,在模板的情况下,这非常容易。为了使A在依赖于X,Y和Z时通过引用或指针工作,我需要有一个基类说X_Interface,我可以从中继承X_Real和X_Fake。
基本上,我最终会为每个需要伪造的课程提供3倍的课程数量。
我很可能错过了一些东西。必须有一种更简单的方法来做到这一点。具有基类X_Interface也非常昂贵,因为我将使用更多空间并进行虚拟调用。我想我可以使用CRTP,因为我知道它在编译时是X_Real还是X_Fake,但仍然必须有更好的方法。
答案 0 :(得分:2)
首先确保你所依赖的对象(X,Y和Z)在构造函数中传入,这样你就可以在测试时轻松传入'fakes'。 (我真的希望你使用单元测试框架,比如CUnit)
现在,在编写测试时,您需要做的就是为被测试的类所依赖的对象组成“假货”。通常你可以传入'null',但是如果你真的需要用'fake'做一些事情,你可以简单地实例化它(你确保它的所有依赖关系都在构造函数中传递,对吧?对!)。
或者在极端情况下,您可以扩展依赖的类,并重新实现一些关键方法以适合您的测试。
所以现在在大多数情况下你不需要'假',有时你只是实例化一个真正的'假',在极少数情况下你有一个额外的类只存在于你的测试代码中。
Look at this video for a much better explanation.
GoogleTechTalks在此主题上有更多内容,但您可以从此处进行管理。
答案 1 :(得分:2)
虽然您经常听说单元测试应该只涵盖一个课程,但根据课程的复杂程度,您可能不必这样做,并且可以同时测试所有3个课程。
你总是要考虑投资回报率。通过单独测试组件与您需要投入多少精力,您将获得多少收益。需要考虑的一些事项:
如果在所有3个类的自动化测试过程中发现错误,是否仍然可以轻松调试它?是这样,考虑同时测试所有3个。
用另一个类(实现相同的接口)替换3个类中的一个是常见的吗?如果是这样,单独测试类可能更有意义。
这三个课程的设计是否只能一起工作?然后同时测试它们。
还要考虑TDD与单元测试不同。 TDD中的测试不一定是纯单元测试。只要您能够以自动方式运行它们,测试就会有很多好处。在我工作的地方,我们的测试套件是纯单元测试和命令行工具的混合,可以执行和验证预期的返回值。
最后注意事项:在绝大多数情况下,拥有纯接口基类所带来的性能并不重要。
答案 2 :(得分:1)
我认为您正在寻找依赖注入框架。请参阅此处的past SO questions。
答案 3 :(得分:0)
不幸的是,强大的编译时类型语言没有太多选择。这实际上没问题,因为良好的架构实践也会促使您向接口编程,而不是实现。为了最大限度地减少模块/类之间的依赖关系,至少应该,例如X_Interface
和X_Real
。在这种情况下,良好的设计和良好的可测试性是相辅相成的。我怀疑很多TDD都会指出完全这一点。