2

I'm using Google Test api to unit test C++ code.

with google test API sample, i see there is a option to test the private methods with FRIEND_TEST macro. Also i see TEST_P,INSTANTIATE_TEST_CASE_P macros for parameterized tests.

So i tried below logic to implement parameterised unit test for private method. But i got an error with 'Foo::Bar' : cannot access private member declared in class 'Foo'. when i try to use the class FRIEND_TEST_Test3 to test with parameterized test macro TEST_P.

So please let me know the possible ways to test private method with parameterised unit test with Google test macros.

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());
}
Prasaathviki
  • 1,147
  • 2
  • 11
  • 22
  • 1
    Personally I would question the value of testing private methods. They are "implementation details". By their very nature, they are not used by client programmers and their "interfaces" are subject to change somewhat more frequently than public methods. – Galik May 10 '19 at 11:45

1 Answers1

2

As stated in the googletest document, the second argument of FRIEND_TEST must be the test name which we want to execute. Since your 3rd unit test is TEST_P(FRIEND_TEST_Test3, Verify) and its test name is Verify, not TEST_P, you have to define FRIEND_TEST(FRIEND_TEST_Test3, Verify) in the private scope of Foo.

In addition, since ::testing::Test is a base class of ::testing::TestWithParam, we don't need to explicitly inherit ::testing::Test to FRIEND_TEST_Test3.

Thus the following code would well work for you:

#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());
}
Hiroki
  • 2,780
  • 3
  • 12
  • 26