Могу ли я избежать насмешек над всеми методами в интерфейсе на С++ при использовании googlemock

Я использую Google Mock 1.6 RC и пытаюсь смоделировать COM Interface. В COM-интерфейсе около 50 методов, некоторые из которых унаследованы от базовых интерфейсов. Когда я создаю макет struct, который наследуется от этого интерфейса и имитирует только те методы, которые я использую, я получаю ошибку cannot instantiate abstract class.

Я хочу знать, можно ли это сделать в googlemock или нет.


person Rishabh    schedule 30.03.2011    source источник
comment
Не знаком с Google Mock, но обычно такие ситуации обрабатываются с помощью класса адаптера.   -  person Vijay Mathew    schedule 30.03.2011


Ответы (3)


Это невозможно сделать. Вы должны перегрузить все чистые виртуальные методы со всех интерфейсов (кроме конструктора и деструктора).

person BЈовић    schedule 30.03.2011
comment
Могу ли я использовать наследование для создания фиктивных объектов. Например, абстрактный класс B наследуется от абстрактного класса A, возможно ли создать MockB, который наследуется от MockA, и каждый из фиктивных классов только издевается над конкретными чистыми виртуальными методами в соответствующих классах. - person Rishabh; 30.03.2011
comment
@rtdecl Да, это вы можете сделать, но вы можете создать экземпляр только со всеми перегруженными чистыми виртуальными методами. - person BЈовић; 30.03.2011
comment
Я попытался создать MockIUnknown, наследующий от IUnknown, и MockIDispatch, наследующий от IDispatch и MockIUnknown. IUnknown имеет 3 чистых виртуальных метода, над которыми я издевался в MockIUnknown, а IDispatch имеет 4 дополнительных чистых виртуальных метода, над которыми я издевался в MockIDispatch. Я могу создать экземпляр MockIUnknown, но не MockIDispatch, я получаю сообщение об ошибке «не могу создать экземпляр абстрактного класса». - person Rishabh; 30.03.2011
comment
@rtdecl Это действительно странно. Вы проверяли подпись методов в MockIDispatch? Может быть, это неправильно. Трудно сказать, не видя кода (или минимального примера, показывающего проблему). - person BЈовић; 30.03.2011

Вы должны переопределить каждый метод, который был объявлен чисто виртуальным в классах, от которых вы прямо или косвенно наследуете. Есть две причины не переопределять их все:

  1. Их слишком много, и вам есть чем заняться, кроме как перебирать их все.
  2. Компиляция фиктивного класса со всеми имитациями выполняется слишком медленно и требует слишком много памяти.

Исправление для (1) заключается в использовании сценария gmock_gen.py в каталоге Google Mock scripts. Он проходит через определение класса и преобразует объявления методов в операторы MOCK_METHOD. Если у вас есть проблемы с (2), вы можете заменить ненужные операторы MOCK_METHOD заглушками:

MOCK_METHOD1(f, bool(int i));

с участием

virtual bool f(int i) {
  thrown std::exception("The stub for f(int) has been invoked unexpectedly.");
}

Генерация исключения предупредит вас о ситуации, когда была вызвана конкретная заглушка, а это означает, что вместо этого вам, вероятно, потребуется смоделировать ее.

Изменить: если исходные интерфейсы для имитации написаны с использованием макросов Microsoft, эта ветка опубликован сценарий, преобразующий их в C++, приемлемый для gmock_gen.py.

person VladLosev    schedule 01.04.2011
comment
› Генерация исключения предупредит вас о ситуации, когда была вызвана конкретная заглушка, а это означает, что вместо этого вам, вероятно, потребуется смоделировать ее. Вы также можете использовать строгий макет, чтобы убедиться, что вызываются только ожидаемые вызовы фиктивного объекта: github.com/google/googletest/blob/master/googlemock/docs/ - person dylam; 12.07.2019

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

В любом случае, разве вы не должны создавать фиктивный класс, а не фиктивную структуру?

Однако в сценариях/генераторе есть инструмент gmock_gen.py, который должен сделать за вас тяжелую работу по созданию макетов для больших классов.

person wojt    schedule 30.03.2011
comment
Destructor не нужно явно имитировать, потому что ваш класс будет иметь деструктор по умолчанию. Я создаю макет struct, потому что com-интерфейс, который я пытаюсь имитировать, представляет собой struct. Я попробую использовать этот скрипт и посмотрю, поможет ли он сократить объем работы. - person Rishabh; 30.03.2011
comment
Я полагаю, вы могли бы взломать скрипт, чтобы он работал и для структур. Я понятия не имею, сколько работы это может быть, хотя. Во всяком случае, в документации Google mock ничего не говорится о насмешливых структурах. - person wojt; 30.03.2011
comment
Класс имитации похож на имитацию структур (crpcut.sourceforge.net/1.2.0/ использование-gmock.html). Я не уверен, насколько просто было бы изменить скрипт, так как я не знаком с Python. - person Rishabh; 30.03.2011
comment
В крайнем случае я бы попытался временно изменить вашу структуру на класс, запустить скрипт, а затем изменить все ключевые слова «класс» на «структура». Хотя это не решение. - person wojt; 30.03.2011