Вы хотите, чтобы Bar
отправлял пакет в обычной работе, но не в тестировании. Таким образом, вам понадобится некоторый код, который запускается при вызове Bar
во время тестирования, даже если это пустая функция. Вопрос в том, где его поставить.
Мы не можем видеть код внутри цикла if(aSendPacket)
, но если он делегирует свою работу какому-то другому классу, тогда мы можем сделать замену там. То есть, если цикл равен
if(aSendPacket)
{
mPacketHandler.send();
}
, чтобы работа выполнялась классом `packetHandler:
// packetHandler.cc
void packetHandler::send()
{
// do some things
// send the packet
}
тогда мы можем сделать "немую" версию класса packetHandler
. (Некоторые назвали бы это заглушкой или фиктивным классом, но, похоже, есть некоторые споры относительно определений этих терминов.)
// version of packetHandler.cc to be used when testing e.g. Foo
void packetHandler::send()
{
// do some things
// don't actually send the packet
}
При тестировании Foo
, скомпилируйте эту версию packetHandler
и свяжите ее. Завод не поймет разницу.
Если, с другой стороны, код для отправки пакета прописан в Foo
, без возможности предотвратить поведение вне класса Foo
, то вам понадобится «тестовая» версия из Foo.cc
(есть другие способы, но они неуклюжи и опасны), и лучший способ сделать это зависит от деталей вашей кодовой базы. Если есть только пара «непроверяемых» функций, подобных этой, то, вероятно, лучше всего поместить Foo::bar(...)
в исходный файл отдельно, с двумя версиями (и сделать то же самое для каждого из других специальных методов). Если их много, то может быть целесообразно получить фабричный класс, специфичный для тестирования, который будет создавать экземпляры, например, class testingFoo : public Foo
который переопределяет Bar
. В конце концов, это то, для чего предназначен абстрактный шаблон фабричного дизайна.