You want Bar
to send a packet in ordinary operation, but not in testing. So you will have to have some code which runs when you call Bar
during testing, even if it's an empty function. The question is where to put it.
We can't see the code inside the if(aSendPacket)
loop, but if it delegates its work to some other class then we can make the substitution there. That is, if the loop is
if(aSendPacket)
{
mPacketHandler.send();
}
so that the work is done by the `packetHandler class:
// packetHandler.cc
void packetHandler::send()
{
// do some things
// send the packet
}
then we can make a "mute" version of the packetHandler
class. (Some would call it a stub or a mock class, but there seems to be somedebate about the definitions of these terms.)
// version of packetHandler.cc to be used when testing e.g. Foo
void packetHandler::send()
{
// do some things
// don't actually send the packet
}
When testing Foo
, compile this version of packetHandler
and link it in. The factory won't know the difference.
If, on the other hand, the code for sending a packet is spelled out in Foo
, with no way to head off the behavior outside the Foo
class, then you will have to have a "testing" version of Foo.cc
(there are other ways but they are clumsy and dangerous), and the best way to do that depends on the details of your codebase. If there are only a couple of "untestable" features like this, then it's probably best to put Foo::bar(...)
in a source file by itself, with two versions (and do the same for each of the other special methods). If there are many then may be worth deriving a factory class specific to testing, which will construct instances of, e.g. class testingFoo : public Foo
which overrides Bar
. After all, this is what the abstract factory design pattern is for.