Как смоделировать приватные методы в классе, который используется публичными методами в Google Test? - PullRequest
0 голосов
/ 26 октября 2018

У меня есть класс, скажем, ClassA, который имеет некоторые публичные функции, а также частные. Публичные функции по очереди класс частных функций. Теперь я собираюсь проверить приватную функцию через публичную функцию. Для публичных функций я пытаюсь вызвать исходную реализацию, а для приватного метода я пытаюсь создать фиктивную функцию.

Мой класс А такой,

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;
    }
};

Теперь у меня есть макет для ClassA, как это,

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
}

Это мой тестовый набор GoogleTest,

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());
}

Как видите, для закрытого метода я использую mock, а для открытого метода я использую Invoke и вызываю исходную реализацию.

Теперь, когда я компилирую этот код, я получаю сообщение об ошибке,

Фактический счетчик вызовов функций не соответствует EXPECT_CALL (a, getCode ()) .... Ожидаемый: будет вызван один раз Актуально: никогда не звонил - неудовлетворен и активен

Теперь, когда я пытаюсь использовать оригинальную реализацию для getCode () также, как,

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

Я получаю сообщение об ошибке компиляции, в котором говорится, что getCode () недоступен, что, я думаю, ожидается.

К настоящему времени, если вы читаете это, надеюсь, вы поняли мою формулировку проблемы. Я должен проверить приватный метод, передав разные аргументы через публичный метод, который я тестирую через gtest.

Я хотел издеваться над закрытым методом, как указано в этой статье в github, и вызывать исходный производственный код для моего открытого метода.

Я делаю что-то в корне неправильно? Если да, может кто-нибудь из вас найдет лучшие методы для моего случая использования.

Я пробовал FRIEND_TEST и tbh, я не хочу никаких изменений в моем рабочем коде. Я попробую это в крайнем случае.

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Поздний ответ, но в настоящее время я работаю над подобными проблемами и видел этот вопрос.

В вашем примере я не совсем уверен, какова цель Invoke(), но если все, что вы пытаетесь сделать, это проверять вызовы к getCode() и контролировать его возвращаемое значение, то вам нужно только посмеяться над этим один.

Вам придется изменить производственный код, чтобы сделать частную функцию виртуальной, поэтому, если это не вариант, то, конечно, это не сработает для вас. Это похоже на довольно безопасную модификацию.

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

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

class MockA : public ClassA {
public:
    MOCK_METHOD1(getCode, int(int value));
};

TEST(ClassATest, Test1)
{
    MockA mockA;
    EXPECT_CALL(mockA, getCode(2)).WillOnce(Return(2));
    EXPECT_EQ(mockA.getName("key"), "XYZ");
}
0 голосов
/ 26 октября 2018

Вы пытаетесь вызвать приватный метод из ClassA. Это невозможно, за исключением случаев, когда есть объявление друга, но да, оно не идеально.

Проблема связана с дизайном вашего теста, который должен вызывать публичный API, а не с деталями реализации.

...