Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过使私有方法成为自由函数来进行单元测试_C++_Unit Testing_Private Methods_Non Member Functions - Fatal编程技术网

C++ 通过使私有方法成为自由函数来进行单元测试

C++ 通过使私有方法成为自由函数来进行单元测试,c++,unit-testing,private-methods,non-member-functions,C++,Unit Testing,Private Methods,Non Member Functions,在2017年cppcon的视频中,我看到了克劳斯·伊尔贝格的一篇演讲,题目是“”。 在这次演讲中,演讲者谈到了如何切换到自由功能 简化测试私有方法的过程(参见19:00)。这个想法是你拉着 私有方法脱离类(您使其成为一个自由函数),它成为可测试的 起初,我觉得这个想法很有趣,但后来 我想得越多,就越不明白这到底是怎么回事。例如 假设我有以下(虚拟)类: 然后someComplexTask()和someOtherComplexTask()是私有方法。这意味着他们 是实现细节,即它们只能在SomeC

在2017年cppcon的视频中,我看到了克劳斯·伊尔贝格的一篇演讲,题目是“”。 在这次演讲中,演讲者谈到了如何切换到自由功能 简化测试私有方法的过程(参见19:00)。这个想法是你拉着 私有方法脱离类(您使其成为一个自由函数),它成为可测试的

起初,我觉得这个想法很有趣,但后来 我想得越多,就越不明白这到底是怎么回事。例如 假设我有以下(虚拟)类:

然后
someComplexTask()
someOtherComplexTask()
是私有方法。这意味着他们 是实现细节,即它们只能在
SomeClass
(或friends)中调用。信息技术 在我看来,如果你让它们成为自由函数,是的,它们是可测试的,但它们不再是 私有,而不仅仅是特定于
SomeClass
的实现细节。事实上,它们可以从代码中的任何地方调用


所以我的问题是:为什么伊格伯格先生的观点是正确的?

我也看过这段视频。但是,我有一些不同意见

1-您的方法是否需要访问字段?如果不是,则它不属于该类。但如果是这样,他们就需要田地。自由函数无权访问字段,除非您将其作为函数参数传递。请考虑自由功能不应被视为公共功能。 2-并不是所有的东西都应该是自由函数。但这是一个很好的做法,避免在不必要的时候把所有东西都放在课堂上

3-私人功能通常不需要测试。但是如果您坚持,您可能能够执行诸如无效黑客(这并不总是像评论中提到的那样有效)之类的操作:

释放你的功能更简洁,但不是更可行

这清楚地表明您存在设计缺陷。如果你有 你需要测试的私有函数,你必须向后弯曲 如果要让它工作,那么就有问题了。你错过了什么。 你的设计不起作用

他的观点不仅仅是让私人功能免费。他并不是说:“获得你所有的私人功能,让它们成为自由功能”。他说需要测试的功能不应该是一个实现细节,因为如果你需要测试它,这表明该功能是有用的

请密切注意他对代码所做的转换:

初始代码:

class X
{
public:
 void doSomething( ... ) {
    ...
    resetValues();
    ...
 }
 ...
private:
 void resetValues() {
     for( int& value : values_ )
        value = 0;
 }
 std::vector<int> values_;
};
现在,
resetValues
是一项可以重用和测试的功能。由于它确实与
X
无关,但通过重置向量的所有值,使其成为自由函数而不是私有
X
方法是一种有效的设计

我喜欢Rann Lifshitz在评论中所说的:


我认为更好的方法是了解一些私人 实际上,函数是公共效用函数


如果有人决定在这里观看视频,这是一个准确的答案time@smac89谢谢,我用你的链接更新了我的问题。我认为这完全取决于那些私有方法的使用。在该视频中,他使用的示例可以很容易地转化为自由函数,因为它的用途非常通用,不依赖于类中的任何内容。我不会从字面上理解那个视频。我认为关键是,您应该能够在代码中找到自由函数与成员函数一样工作的地方,因为自由函数更容易测试。拥有一个私有的重置方法,它可以变成一个可测试的重置(免费)函数,这是一个糟糕的设计。我想他建议的是,将你希望测试的私有函数重构为实用类中的公共函数。在我看来,这仍然比类标题中的自由函数的概念好,但这只是我的拙见。如果你在发布几秒钟后解释你不喜欢这个答案的原因,那就太好了。哦,天哪,不!你做了什么?只需使用适当的测试框架。不要这样做。这里所说的定义正是Klaus Iglberger所说的设计突破解决方案。定义C++关键词是非法的。@ ARASH NO.CUDATABASE <代码>描述了一个有效代码(从标准的角度),使用了一些反模式或是不可读取的,不可维护的等等。你有非法的C++代码。我认为最好的方法是理解一些私有函数实际上是通用效用函数,应该在通用工具类中公开。对我来说,这种方法听起来比使用自由函数要好得多,自由函数是OOP领域中一只奇怪的鸟。@RannLifshitz:“通用实用程序类中应该是公共的公共实用程序函数”-实用程序名称空间比类更合适,对于不共享数据或职责的函数:它们将逻辑分组与头文件分离,并且(通常是好是坏)让客户机程序员可以自由决定是否使用名称空间或特定函数,或者在客户机代码中保持它们的显式性。
#define class struct
#define private public
#define protected public

#include "library.h"

#undef class
#undef private
#undef protected
class X
{
public:
 void doSomething( ... ) {
    ...
    resetValues();
    ...
 }
 ...
private:
 void resetValues() {
     for( int& value : values_ )
        value = 0;
 }
 std::vector<int> values_;
};
void resetValues( std::vector<int>& vec )
{
 for( int& value : vec )
   value = 0;
}