使用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 Test API对C ++代码进行单元测试。

与谷歌测试API示例,我看到有一个选项来测试与FRIEND_TEST宏的私有方法。 我也看到TEST_P,INSTANTIATE_TEST_CASE_P宏用于参数化测试。

因此,我尝试使用以下逻辑为私有方法实现参数化单元测试。 但是我遇到了'Foo :: Bar'错误:无法访问在'Foo'类中声明的私有成员。 当我尝试使用类FRIEND_TEST_Test3来测试带参数的测试宏TEST_P时。

因此,请让我知道使用Google测试宏通过参数化单元测试来测试私有方法的可能方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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());
}


如googletest文档中所述,FRIEND_TEST的第二个参数必须是我们要执行的测试名称。
由于您的第三个单元测试是TEST_P(FRIEND_TEST_Test3, Verify),并且其测试名称是Verify,而不是TEST_P,因此您必须在Foo的私有范围内定义FRIEND_TEST(FRIEND_TEST_Test3, Verify)

另外,由于::testing::Test::testing::TestWithParam的基类,因此我们无需显式继承::testing::TestFRIEND_TEST_Test3

因此,以下代码将很适合您:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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());
}

将测试移到自己的文件(例如test.cpp)。 该文件仅包含测试无效代码。 现在将#define private public添加到-现在您可以访问私有成员,而无需引入奇怪的吸气剂,朋友或测试中的任何内容。

C ++标准说这会导致未定义的行为(在C ++中将私有定义为公共),但对我而言从来没有造成任何问题。

我认为修改我们的代码以使其可测试不是一个好习惯