【发布时间】:2014-10-06 14:47:16
【问题描述】:
如果我有一个类里面有一个助手(私有成员)类,像这样
class Obj;
class Helper {
friend class Obj;
private:
int m_count;
Helper(){ m_count = 0;}; // Note this is a private constructor
void incrementCount(){
++m_count;
};
};
class Obj {
Helper *m_pHelper;
// note that this is a private getter
int getHelperCount() { return m_pHelper->m_count; };
// the public API starts here
public:
Obj() { m_pHelper = new Helper(); };
void incrementCount(){ m_pHelper->incrementCount(); };
};
那么我该如何 TDD 这样的系统呢?
auto obj = new Obj();
obj->incrementCount();
// what to assert???
这是我的问题,以下只是一些背景知识。
对一些答案和cmets的回应。
如果班外没有人感兴趣,那么你的测试也不应该感兴趣。 ——阿恩·默茨
如果没有人对课外的价值感兴趣,你为什么 – utnapistim
即使外部没有人需要该值,我可能仍然想知道它是否设置正确,因为它被使用该值的类的其他自包含内部方法使用。也许该值是控制器将使用它来更新模型的速度。或者也许它是视图将使用它在屏幕上绘制某些东西的位置。事实上,Obj 的所有其他组件都可以访问该变量。这可能是一个糟糕的设计问题,在这种情况下,我想知道我可以有什么更好的选择。该设计列在本文底部的背景部分。
定义私人公共 - 马森毛
喜欢这种巧妙地滥用关键字哈哈。但目前可能还不是最好的解决方案。
你需要在你的班级标题中“暴露”友谊关系。因此,您必须承认存在用于测试您的课程的课程。 如果您使用 pImpl 习语,您可以将 pImpl 本身的成员全部公开,将 pImpl 本身设为私有,并让您的单元测试访问 pImpl - CashCow
这是否意味着我应该在我原来的班级中加入测试?或者向它添加额外的“测试”方法? 我最近才开始 TDD。使用测试类依赖侵入原始类是否常见(或者更好的是)?我认为我没有适当的知识来判断。对此有何建议?
其他:AFAIK TDD 不仅仅是编写测试,而是一个开发过程。我已经读过我应该只将测试写入公共接口。但问题是,就像所讨论的情况一样,大多数代码等都包含在私有类中。如何使用 TDD 创建这些代码?
背景
如果您想知道我为什么要开设私人课程,仅供参考: 我正在从 cocos2dx 开发游戏。游戏引擎采用节点树结构进行更新、渲染等,每个游戏对象都继承自引擎中提供的节点类。现在我想在游戏对象上实现 MVC 模式。因此,对于每个对象,我基本上创建了一个 Object 类,其中包含 3 个帮助类,对应于名为 ObjectModel、ObjectView、ObjectController 的每个 MVC 组件。从理论上讲,没有人应该直接访问 MVC 类,并且只能通过 Object 类以某种方式访问,所以我将它们中的 3 个设为私有。将 MVC 组件显式设为类的原因是因为 View 和 Controller 以不同的速率进行更新(更具体地说,Controller 执行与帧相关的更新,而 View 基于模型数据进行简单的插值)。 Model 类是纯粹出于宗教原因创建的,哈哈。
提前致谢。
【问题讨论】:
-
测试公共接口。
-
当您创建
Obj实例时,Helper实例的计数器应设置为零,您可以对其进行测试。然后递增,并检查结果是否为 1。并且由于“增量计数器”和“获取计数器”是唯一的公共函数,这就是你可以测试的全部。 -
问题是我什至在公共接口中都没有getter。那么我的测试如何检查该值是 0 还是 1?并且故意将 getter 设为私有,因为没有人应该对类之外的值感兴趣。
-
如果类以外的人不应该感兴趣,那么您的测试也不应该感兴趣,因为只要类行为正确,该值是 0 还是 1 或 54 都无关紧要。如果您的类需要某个公开可用函数的该值,请测试该函数。如果您的类在公共接口中的任何函数都不需要该值,则将值全部丢弃,因为它根本没有用。如果您要测试的是您的类所依赖的一些更通用的算法,则将其放入自己的类中并单独对其进行单元测试。