使用 Google test API for C++ 的参数化单元测试来测试私有方法的可能方法是什么?
What are the possible ways to test private methods with a parameterised unit test with Google test API for C++?
我正在使用 Google 测试 api 对 C++ 代码进行单元测试。
用 google 测试 API 样本,我看到有一个选项可以用 FRIEND_TEST 宏测试私有方法。我还看到了用于参数化测试的 TEST_P、INSTANTIATE_TEST_CASE_P 宏。
所以我尝试了以下逻辑来实现私有方法的参数化单元测试。但是 'Foo::Bar' 出现错误:无法访问 class 'Foo' 中声明的私有成员。当我尝试使用 class FRIEND_TEST_Test3 来测试参数化测试宏 TEST_P 时。
所以请让我知道用 Google 测试宏测试参数化单元测试私有方法的可能方法。
class Foo {
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test, TEST);
FRIEND_TEST(FRIEND_TEST_Test2, TEST_F);
FRIEND_TEST(FRIEND_TEST_Test3, TEST_P);
};
TEST(FRIEND_TEST_Test, TEST) {
ASSERT_EQ(1, Foo().Bar());
}
class FRIEND_TEST_Test2 : public ::testing::Test {
public:
Foo foo;
};
TEST_F(FRIEND_TEST_Test2, TEST_F) {
ASSERT_EQ(1, foo.Bar());
}
class CodeLocationForTESTP : public ::testing::TestWithParam<int> {
};
INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, ::testing::Values(0,1,2,1,0));
TEST_P(CodeLocationForTESTP, Verify) {
ASSERT_TRUE(0==GetParam());
}
class FRIEND_TEST_Test3 : public ::testing::Test,public ::testing::TestWithParam<int> {
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify) {
ASSERT_EQ(1, foo.Bar());
}
将您的测试移动到自己的文件中(例如 test.cpp
)。该文件只允许包含测试和非生产性代码。现在将 #define private public
添加到 - 现在您可以访问私有成员,而无需在您的测试中引入奇怪的吸气剂、朋友或任何东西。
C++ 标准说这会导致未定义的行为 (Define private to public in C++),但它从未对我造成任何问题。
我认为修改我们的代码使其可测试不是一个好的做法
如the googletest document所述,FRIEND_TEST
的第二个参数必须是我们要执行的测试名称。
由于您的第三个单元测试是 TEST_P(FRIEND_TEST_Test3, Verify)
并且其测试名称是 Verify
,而不是 TEST_P
,因此您必须在 Foo
的私有范围内定义 FRIEND_TEST(FRIEND_TEST_Test3, Verify)
。
此外,由于::testing::Test
是::testing::TestWithParam
的基础class,我们不需要显式继承::testing::Test
到FRIEND_TEST_Test3
。
因此下面的代码很适合您:
#include <gtest/gtest.h>
#include <gtest/gtest_prod.h>
class Foo
{
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test3, Verify);
// ^^^^^^ not TEST_P
};
class FRIEND_TEST_Test3 : public ::testing::TestWithParam<int>
{
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify)
{
ASSERT_EQ(1, foo.Bar());
}
我正在使用 Google 测试 api 对 C++ 代码进行单元测试。
用 google 测试 API 样本,我看到有一个选项可以用 FRIEND_TEST 宏测试私有方法。我还看到了用于参数化测试的 TEST_P、INSTANTIATE_TEST_CASE_P 宏。
所以我尝试了以下逻辑来实现私有方法的参数化单元测试。但是 'Foo::Bar' 出现错误:无法访问 class 'Foo' 中声明的私有成员。当我尝试使用 class FRIEND_TEST_Test3 来测试参数化测试宏 TEST_P 时。
所以请让我知道用 Google 测试宏测试参数化单元测试私有方法的可能方法。
class Foo {
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test, TEST);
FRIEND_TEST(FRIEND_TEST_Test2, TEST_F);
FRIEND_TEST(FRIEND_TEST_Test3, TEST_P);
};
TEST(FRIEND_TEST_Test, TEST) {
ASSERT_EQ(1, Foo().Bar());
}
class FRIEND_TEST_Test2 : public ::testing::Test {
public:
Foo foo;
};
TEST_F(FRIEND_TEST_Test2, TEST_F) {
ASSERT_EQ(1, foo.Bar());
}
class CodeLocationForTESTP : public ::testing::TestWithParam<int> {
};
INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, ::testing::Values(0,1,2,1,0));
TEST_P(CodeLocationForTESTP, Verify) {
ASSERT_TRUE(0==GetParam());
}
class FRIEND_TEST_Test3 : public ::testing::Test,public ::testing::TestWithParam<int> {
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify) {
ASSERT_EQ(1, foo.Bar());
}
将您的测试移动到自己的文件中(例如 test.cpp
)。该文件只允许包含测试和非生产性代码。现在将 #define private public
添加到 - 现在您可以访问私有成员,而无需在您的测试中引入奇怪的吸气剂、朋友或任何东西。
C++ 标准说这会导致未定义的行为 (Define private to public in C++),但它从未对我造成任何问题。
我认为修改我们的代码使其可测试不是一个好的做法
如the googletest document所述,FRIEND_TEST
的第二个参数必须是我们要执行的测试名称。
由于您的第三个单元测试是 TEST_P(FRIEND_TEST_Test3, Verify)
并且其测试名称是 Verify
,而不是 TEST_P
,因此您必须在 Foo
的私有范围内定义 FRIEND_TEST(FRIEND_TEST_Test3, Verify)
。
此外,由于::testing::Test
是::testing::TestWithParam
的基础class,我们不需要显式继承::testing::Test
到FRIEND_TEST_Test3
。
因此下面的代码很适合您:
#include <gtest/gtest.h>
#include <gtest/gtest_prod.h>
class Foo
{
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test3, Verify);
// ^^^^^^ not TEST_P
};
class FRIEND_TEST_Test3 : public ::testing::TestWithParam<int>
{
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify)
{
ASSERT_EQ(1, foo.Bar());
}