Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock private methods in a class which is being used by public methods in Google Test?

I have a class, say ClassA which has some public functions as well as private. The public functions in turns class private functions. Now my intention here is to test the private function via public function. For Public functions, I am trying to invoke the original implementation and for private method I am trying to create a Mock function.

My Class A is like this,

class ClassA {
public:
    string getName(string key) {
        int value = 2;
        int code = getCode(value);
        if(code != 2)
             cout<<"Error";
        else
             return "XYZ";
    }

private:
    int getCode(int value) {
        if(value == 2)
             return 2;
        else
             return -1;
    }
};

Now I have a Mock for the ClassA like this,

class MockA : public ClassA {
       public:
       MOCK_METHOD1(getName,string(string key)); //Mock for public method
       MOCK_METHOD1(getCode,int(int value))l //Mock for private method
}

This is my GoogleTest test case,

TEST(ClassATest, Test1)
{
    MockA a;
    Class a1;

    EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(2));
    EXPECT_CALL(a,getName()).Times(1).WillOnce(Return(Invoke(&a1, 
ClassA::getName());
}

As you can see, for the private method I am using mock and for public method I am using Invoke and invoking the original implementation.

Now, when I compile this code, I get an error,

Actual function call count doesn't match EXPECT_CALL(a,getCode()).... Expected : to be called once Actual : never called - unsatisfied and active

Now when I try to use orginal Implementation for getCode() also like,

EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(Invoke(&a1, 
ClassA::getCode());

I get an compilation error saying getCode() is inaccesible which I think is expected.

By now, if you are reading this, hope you are understood my problem statement. I have to test the private method by passing in different arguments, via the public method which I test via gtest.

I wanted to mock the private method as stated by this article in github and call the orininal production code for my public method.

Am I doing something fundamentally wrong? If so, can any of you some better methods for my use case.

I have tried FRIEND_TEST and tbh, I dont want any modifications in my production code. I will try that as a last resort.

like image 361
Shaik Syed Ali Avatar asked Sep 20 '25 02:09

Shaik Syed Ali


1 Answers

You are trying to invoke a private method from ClassA. This is not possible except if there is a friend declaration, but yes, it's not ideal.

The problem stems from the design of your test which should call a public API and not an implementation detail.

like image 191
Matthieu Brucher Avatar answered Sep 22 '25 18:09

Matthieu Brucher