单元测试变量的真假
Unit test a variable for both true and false
我正在使用 googletest/googlemock 编写 C++ 生产代码。我在使用 A.cpp:
中的一个函数时偶然发现了这个想法
bool A::process_(false);
bool A::process()
{
if ( !process_ ){
process_ = true;
}
return process_;
}
其中 header 包含:
protected:
static bool process_;
public:
static bool process();
我被困在这样一种方式中,我只能测试函数的预期输出为 true 或输入为 false,如下所示:
TEST(ATest, processVal){
A a;
EXPECT_TRUE(a.process());
}
有没有一种方法可以测试该函数,以便通过 process_
的 *true*
和 *false*
值?这样测试就涵盖了两者的决定。
我在考虑模拟,以便它可以预期对 true 和 false 的调用,但因为它不是 class 成员中的函数,我猜你不能对 process_ 进行模拟?
如果可以,如何模拟变量?
注意:我正在使用 linux 和 gcc :) 谢谢!
声明 A
的子类。由于 process_
是 protected
,您可以在 运行 测试之前使用 A to set it to
trueor
false` 的子类。
- 解决方案 1: 从测试中访问任何
protected
attribute/method
不修改生产代码
你可以很容易地修改_process
即使被保护,只需这样做:
class SubA : public A
{
public:
void setProcess( bool val ) { process_ = val; }
};
A a;
SubA* pA = (SubA*) &a;
pA->setProcess( false );
这会很好用而且很安全。即使你将 A*
强制转换为 SubA*
这不是真正有效的,它也会起作用,因为内存中的 SubA
对象与 A
对象相同(因为 SubA
没有声明任何额外的属性)。
这只有效,因为 process_
是 protected
,所以您创建派生的 class SubA
并使用它,因为编译器将允许此子 class访问受保护的内容。
- 解决方案 2: 从测试中访问任何
protected
甚至 private
attribute/method不修改生产代码
现在,如果 process_
是 private
,这将不起作用...但是,private
/protected
仅由编译器管理...属性在内存中,即使您不是 "allowed to".
也可以访问它们
它很丑,但效果很好:
#define protected public
#define private public
#include "A.h"
#undef private
#undef protected
{
A a;
a._process = false;
}
这个 hack 可以很容易地从您的测试程序访问任何 private
/protected
attributes/functions。
我正在使用 googletest/googlemock 编写 C++ 生产代码。我在使用 A.cpp:
中的一个函数时偶然发现了这个想法bool A::process_(false);
bool A::process()
{
if ( !process_ ){
process_ = true;
}
return process_;
}
其中 header 包含:
protected:
static bool process_;
public:
static bool process();
我被困在这样一种方式中,我只能测试函数的预期输出为 true 或输入为 false,如下所示:
TEST(ATest, processVal){
A a;
EXPECT_TRUE(a.process());
}
有没有一种方法可以测试该函数,以便通过 process_
的 *true*
和 *false*
值?这样测试就涵盖了两者的决定。
我在考虑模拟,以便它可以预期对 true 和 false 的调用,但因为它不是 class 成员中的函数,我猜你不能对 process_ 进行模拟?
如果可以,如何模拟变量?
注意:我正在使用 linux 和 gcc :) 谢谢!
声明 A
的子类。由于 process_
是 protected
,您可以在 运行 测试之前使用 A to set it to
trueor
false` 的子类。
- 解决方案 1: 从测试中访问任何
protected
attribute/method 不修改生产代码
你可以很容易地修改_process
即使被保护,只需这样做:
class SubA : public A
{
public:
void setProcess( bool val ) { process_ = val; }
};
A a;
SubA* pA = (SubA*) &a;
pA->setProcess( false );
这会很好用而且很安全。即使你将 A*
强制转换为 SubA*
这不是真正有效的,它也会起作用,因为内存中的 SubA
对象与 A
对象相同(因为 SubA
没有声明任何额外的属性)。
这只有效,因为 process_
是 protected
,所以您创建派生的 class SubA
并使用它,因为编译器将允许此子 class访问受保护的内容。
- 解决方案 2: 从测试中访问任何
protected
甚至private
attribute/method不修改生产代码
现在,如果 process_
是 private
,这将不起作用...但是,private
/protected
仅由编译器管理...属性在内存中,即使您不是 "allowed to".
它很丑,但效果很好:
#define protected public
#define private public
#include "A.h"
#undef private
#undef protected
{
A a;
a._process = false;
}
这个 hack 可以很容易地从您的测试程序访问任何 private
/protected
attributes/functions。