如何在进行 GoogleTest 时跳过源代码中的部分“代码”
How to Skip a Portion of the ”Code” in the source code while doing GoogleTest
我尝试在源代码中使用调试标志添加 (GOOGLE_TEST) 并将其定义在 TEST/Makefile.am 中。但事情没有奏效。我正在使用 C++ 语言。
注意:我不想更改 SRC 目录代码中的任何内容,这会影响生产代码及其 Makefile.am
在 SRC 目录中测试 Class
class Common: public Thread {
public:
friend class test_common;
Common {
}
~Common () {
}
virtual void ThreadMain();
protected:
virtual void ProcessData(void);
};
void Common::ProcessData(void) {
#ifndef __GOOGLE_TEST__
while (1) { }
#endif
}
测试目录中的 TESTCODE
class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
Common commonObj();
commonObj. ProcessData ();
}
输出
即使在 test/makefile.am
中定义标志后,GTest 仍卡在 While 循环部分
无法使一个编译单元的 #define
值影响另一个先前编译单元的编译。鉴于您已规定不想做的事情列表,您将不得不使用某种形式的运行时恶作剧。
您可以让 ProcessData 接受一个参数来确定循环是否应该迭代:
void ProcessData(bool once=false);
void Common::ProcessData(bool once) {
do {
// ... your loop code
} while (!once);
}
或者您可以使用在模块中定义的全局变量,其中包含您的 main()
,我们称之为 main.cpp
。
生产 main.cpp
:
const bool g_isDebugMode = false;
单元测试main.cpp
:
const bool g_isDebugMode = true;
main.h
extern const bool g_isDebugMode;
现在您可以针对此变量编写运行时测试。
do {
// your code
} while (g_isDebugMode == false);
不要依赖编译标志,在不影响生产代码的情况下使用 GMOCK 方法摆脱 while (1) 循环,代码可以像下面这样:
测试代码:
class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
Common commonObj();
ON_CALL(mock_if, GetBool())
.WillByDefault(Return(true));
EXPECT_CALL(mock_if, GetBool())
.Times(AtLeast(1))
.WillOnce(Return(true))
.WillOnce(Return(false));
commonObj. ProcessData ();
}
摘要代码:
class AbstractIf {
public:
AbstractIf (void) = default;
virtual ~AbstractIf (void) = default;
virtual bool GetBool() = 0;
};
模拟代码:
class MockIf : public AbstractIf {
public:
MOCK_METHOD0(GetBool,bool());
};
源代码:
class Common: public Thread {
public:
friend class test_common;
Common {
}
~Common () {
}
virtual void ThreadMain();
protected:
virtual void ProcessData(void);
AbstractIf *prov_fl_if_;
};
void Common::ProcessData(void) {
while (prov_fl_if_->GetBool()) { }
}
通过这种方式我们可以跳过我们想要的部分代码而不影响生产代码
我尝试在源代码中使用调试标志添加 (GOOGLE_TEST) 并将其定义在 TEST/Makefile.am 中。但事情没有奏效。我正在使用 C++ 语言。 注意:我不想更改 SRC 目录代码中的任何内容,这会影响生产代码及其 Makefile.am
在 SRC 目录中测试 Class
class Common: public Thread {
public:
friend class test_common;
Common {
}
~Common () {
}
virtual void ThreadMain();
protected:
virtual void ProcessData(void);
};
void Common::ProcessData(void) {
#ifndef __GOOGLE_TEST__
while (1) { }
#endif
}
测试目录中的 TESTCODE
class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
Common commonObj();
commonObj. ProcessData ();
}
输出
即使在 test/makefile.am
中定义标志后,GTest 仍卡在 While 循环部分无法使一个编译单元的 #define
值影响另一个先前编译单元的编译。鉴于您已规定不想做的事情列表,您将不得不使用某种形式的运行时恶作剧。
您可以让 ProcessData 接受一个参数来确定循环是否应该迭代:
void ProcessData(bool once=false);
void Common::ProcessData(bool once) {
do {
// ... your loop code
} while (!once);
}
或者您可以使用在模块中定义的全局变量,其中包含您的 main()
,我们称之为 main.cpp
。
生产 main.cpp
:
const bool g_isDebugMode = false;
单元测试main.cpp
:
const bool g_isDebugMode = true;
main.h
extern const bool g_isDebugMode;
现在您可以针对此变量编写运行时测试。
do {
// your code
} while (g_isDebugMode == false);
不要依赖编译标志,在不影响生产代码的情况下使用 GMOCK 方法摆脱 while (1) 循环,代码可以像下面这样:
测试代码:
class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
Common commonObj();
ON_CALL(mock_if, GetBool())
.WillByDefault(Return(true));
EXPECT_CALL(mock_if, GetBool())
.Times(AtLeast(1))
.WillOnce(Return(true))
.WillOnce(Return(false));
commonObj. ProcessData ();
}
摘要代码:
class AbstractIf {
public:
AbstractIf (void) = default;
virtual ~AbstractIf (void) = default;
virtual bool GetBool() = 0;
};
模拟代码:
class MockIf : public AbstractIf {
public:
MOCK_METHOD0(GetBool,bool());
};
源代码:
class Common: public Thread {
public:
friend class test_common;
Common {
}
~Common () {
}
virtual void ThreadMain();
protected:
virtual void ProcessData(void);
AbstractIf *prov_fl_if_;
};
void Common::ProcessData(void) {
while (prov_fl_if_->GetBool()) { }
}
通过这种方式我们可以跳过我们想要的部分代码而不影响生产代码