Search code examples
c++c++11inheritancegoogletestprotected

How to test a protected member from multiple inheritance in GoogleTest?


Imagine I have a Foo class which contains a protected member. Foo is my template base class. Then I have a Bar class, which inherits from Foo. The protected member will be private within Bar.

I need to make a test which I need to access the protected member from my Foo base class as seen below.

#include <gtest/gtest.h>

template <typename T>
class Foo
{
public:
    int set() { mMember=1; }    
protected:
    int mMember;
};

class Bar : public Foo<int>
{};


namespace
{
    class myTestUT : public Foo<Bar>, public testing::Test { };

    TEST_F(myTestUT, how_can_i_test_this){
        Bar bar;
        bar.set(); // ALL GOOD, set() is public!

        ASSERT_EQ(bar.mMember, 1); // ERROR! mMember is protected! Why can't I access it since I am inheriting it?
    }
}

On my test setup I have class myTestUT : public Foo<Bar> which will be a bridge to have access to the Foo members (public and protected), so why can't I access my mMember method?

Please note that I know that mMember could be set on the constructor of Foo, but that is not the question here as I created this small snippet to illustrate my problem.

I saw this question, but this doesn't contain my problem with multiple-inheritance.


Solution

  • why can't I access my mMember method?

    It is not my mMember, it is bar's member.

    GoogleTest manual:

    When you need to test the private or protected members of a class, use the FRIEND_TEST macro to declare your tests as friends of the class.

    template <typename T>
    class Foo
    {
    public:
        void set() { mMember=1; }    
    protected:
        int mMember;
        FRIEND_TEST(myTestUT, how_can_i_test_this);
    };
    
    class Bar : public Foo<int>
    {};
    
    class myTestUT : public Foo<Bar>, public testing::Test { };
    
    TEST_F(myTestUT, how_can_i_test_this){
        Bar bar;
        bar.set();
    
        ASSERT_EQ(bar.mMember, 1);
    }
    

    You have to remove the unnamed namespace, or use a named namespace. https://godbolt.org/z/3h8q96Ecj