C++ 如何使用UnitTest+;从测试访问私有类字段+;?
我在使用编写单元测试代码时遇到了麻烦。我想知道如何以干净的方式(或者任何方式)访问私有成员类字段 到目前为止,我已经有了一个解决方案,可以使用从被测类派生的类fixture来访问受保护的成员。下面的代码显示了这个想法:C++ 如何使用UnitTest+;从测试访问私有类字段+;?,c++,unit-testing,unittest++,C++,Unit Testing,Unittest++,我在使用编写单元测试代码时遇到了麻烦。我想知道如何以干净的方式(或者任何方式)访问私有成员类字段 到目前为止,我已经有了一个解决方案,可以使用从被测类派生的类fixture来访问受保护的成员。下面的代码显示了这个想法: struct MyFixture : ClassUnderTest { }; TEST_FIXTURE(MyFixture, OneTest) { do_something(); CHECK(protected_field == true); } 尽管如此,我
struct MyFixture : ClassUnderTest { };
TEST_FIXTURE(MyFixture, OneTest)
{
do_something();
CHECK(protected_field == true);
}
尽管如此,我认为这并不是很干净,因为在某些配置中可能会出现与继承相关的问题,而且,无论如何,只能访问和测试受保护的成员
我试图将测试类声明为好友,但由于这些测试类是由UnitTest++以某种特殊的方式创建的,所以我还没有做到这一点
有人知道如何让测试类成为测试类的朋友吗
有没有其他更简单或不同的方法来解决这个问题
提前谢谢大家。有一个非常难看但非常有用的hack,我通常用于单元测试:
#define private public
#define protected public
#include "class_to_be_tested.h"
// and here, all class's methods and fields are public :P
不要将它用于单元测试以外的任何事情
此外,这种方法也有一些局限性——首先,并非所有private都以private
作为前缀。其次,一个流行的编译器将访问说明符转换为链接器符号
另一个,也不是很好的方法是通过铸造。您创建了一个具有相同字段但都是公共字段的结构,并将其转换为指向私有结构的指针。但是,这有一个缺点,即类需要精确匹配:
class my_class
{
private:
char name[40];
char grade;
int age;
public:
//
}
struct my_class_hack
{
public:
char name[40];
char grade;
int age;
}
struct hack_it* my_class_hacked = (my_class_hack*)ptr;
。。。但是,如果编译器玩弄您的代码,您可能会得到令人不快的惊喜,因此千万不要将其用于生产代码。几年前,这是一个激烈争论的主题,但普遍接受的结果是,您应该只测试类的外部可见行为,因此,不需要访问其内部数据和行为
虽然这听起来可能没有帮助,但您可以将要测试的类的私有部分提取到新类中,这些类的外部行为就是您要测试的行为。然后,您可以以正常的方式测试这些类,从而改进您的总体设计。最好避免测试私人物品。为什么要测试一个私有字段?当private_字段设置为无效值时,会出现什么错误?是否可以测试这种错误的行为,而不是断言错误的值 其他选择包括
- 在编译代码进行单元测试时,使用预处理器将其公开
- 将私有字段和相关逻辑提取到一个新类中,该类将是公共的,并使被测类依赖于这个新类
但是,如果您绝对需要测试私有函数,下面是我根据自己的喜好考虑的方法的列表:
details
或internal
。不要在头文件中声明它,只需在定义类函数的同一文件中定义它。将其声明添加到单元测试项目的myClass_internal.h
头文件中,并对其进行测试。所涉及的困难很大程度上取决于体系结构的复杂性5.)从您的角度来看,这是正确的,我宁愿使用丑陋的测试代码,而不是丑陋的生产代码:)虽然我同意大家说的“不要那样做”,但有时您在一个大型项目中工作,您没有自由对测试中的类进行您想要的所有更改。对于这些情况,我更喜欢朋友声明,而不是公共/私人重新定义黑客 我想好了该怎么做了 下面是一个“Deck”类的示例,其中包含一个“dealInternal”受保护/私有方法,您希望从“internal”测试中使用该方法
-1只适用于黑客。对不起,如果可能的话,为什么不让代码变得更好而不是使用黑客呢?@Dmitry:一旦你进入现实世界,你就会知道神秘的
客户机
永远不会让你有时间写“更好的代码”,但会要求98%的代码覆盖率——那时候你就可以学会爱和爱了
//------------- Deck.h -------------
namespace SuiteDeck { class TestInternals; }
class Deck {
// etc...
private:
friend class SuiteDeck::TestInternals;
bool dealInternal();
};
//------------ TestDeck.cpp ----------
#include "UnitTest++.h"
#include "Deck.h"
SUITE(Deck) {
TEST(Internals) {
Deck d;
CHECK(d.dealInternal() == true); // or whatever
}
}