On
many occasions, we may want to test a real object by passing to it
prepared buffers of data (characters, bytes, etc.) that are filled in
when the object calls a mock method. This can be achieved by using SetArrayArg.
Suppose we have a Client object that implements a find method, which takes an array of characters as input argument. The method queries a Driver object for chunks of data (other arrays of characters of the same size as the input argument) and compares each chunk with the input array:
void Client::find(char * buf)
{
char tmp_buf[buflen];
bool found = false;
while(!found && _drv.getDataChunk(tmp_buf))
{
int i = 0;
while(i < buflen && buf[i] == tmp_buf[i])
{
i++;
}
if(i == buflen)
found = true;
}
if(found)
cout << "Found matching chunk of data." << endl;
else
cout << "No matching chunk of data found." << endl;
}
Client assumes that Diver implements the following contract:
class DriverSuppose we have a Client object that implements a find method, which takes an array of characters as input argument. The method queries a Driver object for chunks of data (other arrays of characters of the same size as the input argument) and compares each chunk with the input array:
void Client::find(char * buf)
{
char tmp_buf[buflen];
bool found = false;
while(!found && _drv.getDataChunk(tmp_buf))
{
int i = 0;
while(i < buflen && buf[i] == tmp_buf[i])
{
i++;
}
if(i == buflen)
found = true;
}
if(found)
cout << "Found matching chunk of data." << endl;
else
cout << "No matching chunk of data found." << endl;
}
Client assumes that Diver implements the following contract:
- if there is no more data chunks, getDataChunk will return false,
- otherwise, it will return true and will fill in the buffer passed to it through pointer as input, with next chunk of data.
{
public:
virtual ~Driver() {}
virtual bool getDataChunk(char *) = 0;
};
class MockDriver : public Driver
{
public:
MOCK_METHOD1(getDataChunk, bool(char *));
};
Let's now consider a test in which we want to simulate that a matching chunk of data is found on the first call of getDataChunk.
TEST(ClientTest, FindsAMatchOnFirstCall)
{
MockDriver drv;
Client client(drv);
//this is the buffer that will be searched for
char buf [] = {'a','a','a','a','a','a','a','a'};
//this is the matching buffer that will be returned by MockDriver
char bufA [] = {'a','a','a','a','a','a','a','a'};
EXPECT_CALL(drv, getDataChunk(_))
.Times(1) //we are expecting just one call, since the first call will return the matching buffer
//the mock will return true and before doing so it will copy the contents of bufA into the table
//pointed to by the pointer passed to getDataChunk method as the input parameter .WillOnce(DoAll(SetArrayArgument<0>(bufA, bufA+8), Return(true)));
client.find(buf);
}
Exercise: try to modify the code above to validate your expectations on Client::find method when there is no matching chunk of data.