Var*_*una 4 c++ tdd unit-testing
我正在学习单元测试,并想知道如何编写可测试的代码.但是,我不确定如何在不使其复杂的情况下编写可测试代码.我将采用着名的汽车和发动机问题来描述问题.
class Car
{
private:
Engine m_engine;
public:
Car();
// Rest of the car
}
Run Code Online (Sandbox Code Playgroud)
我提出了以下解决方案,以使上述代码可测试.
更改Car的构造函数以将Engine作为参数.然后模拟引擎并进行测试.但是,如果我没有不同类型的引擎,那么参数化构造函数似乎是不合适的,只是为了使它可测试.
使用setter然后将模拟引擎传递给setter.与上述相同的流程.
首先测试引擎,然后使用经过验证的引擎(或使用存根引擎)测试汽车.
我必须在代码上测试哪些替代方案?每种方法的优点和缺点是什么?
从不同的(测试驱动开发)观点来看:易于测试的代码易于使用.编写单元测试实际上是在测试代码的"公共接口".如果它很难测试,那是因为你在那里有一些依赖,这使得它很难.你真的需要一个遏制关系,还是一个联想关系会更有意义?
在你的情况下,我个人认为在构造函数中传递Engine会更容易测试,所以我会像你的建议#1那样重构构造函数.您可以在一个测试套件中测试引擎,并提供一个模拟引擎来测试另一个测试套件中的Car.现在测试它很简单,这意味着界面易于使用.这是好事.
现在考虑如何在实际项目中使用该实现.您将创建一个CarFactory类,工厂将创建一个引擎并将其放入Car中,然后再将其交付给您.(还要注意这最终如何更接近地模拟汽车,发动机和工厂的真实世界,但我离题了.)
因此,TDD的答案是重构代码以在构造函数上获取Engine指针.
如果您只有一个引擎类型,为什么要尝试将其作为新对象?如果您不打算交换引擎,请不要创建另一个抽象层.只需将发动机作为汽车的一部分.
您可能正在分解以降低复杂性,而不是重用组件.好决定.在这种情况下,我会说3是你最好的选择 - 验证你的低级组件,然后使用调用较低级别对象的更高级代码.
实际上,Engine更像是数据库.并且您将需要更改构造函数以使用不同的数据库(出于测试原因或其他原因),但您可以暂时搁置该谎言.