GMock поддерживает так называемое внедрение зависимостей hi-perf для насмешливых не виртуальных методов .
Суть, по ссылке выше, заключается в использовании шаблонов:
template <class PacketStream>
void CreateConnection(PacketStream* stream) { ... }
template <class PacketStream>
class PacketReader {
public:
void ReadPackets(PacketStream* stream, size_t packet_num);
};
Затем вы можете использовать CreateConnection () и PacketReader в производственном коде, а также использовать CreateConnection () и PacketReader в тестах.
Для функций C они рекомендуют интерфейсы, поэтому, вероятно, не то, что вам нужно. Однако, если у вас есть отдельные библиотеки, вы всегда можете связать их с библиотекой тестирования, которая содержит функции с теми же сигнатурами, что и у библиотеки развертывания. Вы даже можете сделать это динамически с LD_PRELOAD, если вы чувствуете себя особенно смелым. Это звучит как много ссылок на меня.
Cxxtest , если вы посмотрите в разделе 8.1 в расширенные функции поддерживает некоторые макросы для упрощения использования / создания интерфейсов:
Из этой ссылки:
CXXTEST_MOCK_GLOBAL( time_t, /* Return type */
time, /* Name of the function */
( time_t *t ), /* Prototype */
( t ) /* Argument list */ );
8.1.2. Mock Functions in Tested Code
Протестированный код использует фиктивные глобальные функции, а не напрямую использует глобальные функции. Вы получаете доступ к фиктивным функциям в пространстве имен T (для теста), поэтому тестируемый код вызывает T :: time () вместо time (). Это эквивалентно использованию абстрактных интерфейсов вместо конкретных классов.
// rand_example.cpp
#include <time_mock.h>
int generateRandomNumber()
{
return T::time( NULL ) * 3;
}
В прошлом мне повезло с подходом Cxxtest.