非公开功能应该进行单元测试吗?

dla*_*nod 8 c++ unit-testing

我正在为我的一些代码编写单元测试,并遇到了一个情况,我有一个具有小暴露接口但内部结构复杂的对象,因为每个公开的方法都会运行大量内部函数,包括对象状态的依赖性.这使得外部接口上的方法很难进行单元测试.

我最初的问题是我是否应该单独测试这些内部函数,因为它们更简单,因此更容易编写测试?我的直觉是肯定的,这导致后续问题,如果是这样,我将如何在C++中这样做呢?

我提出的选项是将这些内部函数从private更改为protected,并使用friend类或inheritence来访问这些内部函数.这是执行此操作的最佳/唯一方法是保留隐藏内部方法的一些语义吗?

Ate*_*ral 16

如果您的对象执行非常难以通过有限的公共接口测试的高度复杂的操作,则可以选择将一些复杂的逻辑分解为封装特定任务的实用程序类.然后,您可以单独对这些类进行单元测试 将代码组织成易于理解的块总是一个好主意.


dmc*_*kee 11

简短回答:是的.

关于如何,我几天前在SO上找到了一个传递参考:

#define private public
Run Code Online (Sandbox Code Playgroud)

在读取相关标题之前评估的单元测试代码中...
同样用于受保护.

很酷的主意.


稍微长一点的答案:测试代码是否明显正确.这意味着任何代码都可以做一些非平凡的事情.


考虑一下,我对此感到疑惑.您将无法链接到在生产版本中使用的同一对象文件.现在,单元测试是一个人为的环境,所以也许这不是一个交易破坏者.任何人都可以阐明这个伎俩的利弊吗?


j_r*_*ker 5

我个人认为,如果测试公共接口不足以充分测试私有方法,您可能需要进一步分解类.我的理由是:私有方法应该只做足以支持公共接口的所有用例.

但是我的单元测试经验(不幸的是)很小; 如果有人可以提供一个令人信服的例子,其中大量的私人代码无法分开,我当然愿意重新考虑!


And*_*ein 5

有几种可能的方法.假设你的班级是X:

  1. 只使用X的公共接口.您将遇到大量的设置问题,可能需要一个覆盖工具来确保您的代码被覆盖,但不涉及任何特殊的技巧.
  2. 使用"#define private public"或类似的技巧来链接暴露给所有人的Xo版本.
  3. 添加一个公共的"static X :: unitTest()"方法.这意味着您的代码将链接到您的测试框架.(但是,我合作过的一家公司使用它来远程诊断软件.)
  4. 添加"class TestX"作为X的朋友.您的生产dll/exe中未附带TestX.它仅在您的测试程序中定义,但它可以访问X的内部.
  5. 其他...