I know this has been asked multiple times but none of the answers work for me. This is the mocked func I want to test:
MOCK_METHOD2(sendInternal, void(uint8_t data[], uint8_t size));
The test goes like this
uint8_t expectedMessageData[3] = { 0x08, 0xda, 0xff };
EXPECT_CALL(*serverFake, sendInternal(testing::_,3))
.With(testing::Args<0, 1>(ElementsAre(0x08, 0xda, 0xff)))
.Times(1);
But this results in
Expected args: are a tuple whose fields (#0, #1) has 2 elements where element #0 is equal to '\b' (8), element #1 is equal to '\xDA' (218) Actual: don't match, whose fields (#0, #1) are (0x7fcfd9500590, '\x11' (3)), which has 3 elements
To me it seems like Gmock would compare the params and not the array's elements.
I've even built a custom matcher:
MATCHER_P2(HasBytes, bytes, size, "") {
uint8_t * dataToCheck = arg;
bool isMatch = (memcmp(dataToCheck, bytes, size) == 0);
return isMatch;
}
I can see (while debugging) that isMatch == true but the test still fails.
Please help!
First of all, I did not reproduce your problem. The following example compiles and the test passes:
class ServerFake {
public:
MOCK_METHOD2(sendInternal, void(uint8_t data[], uint8_t size));
};
// If only possible, I recommend you to use std::vector instead of raw array
class ServerFake2 {
public:
MOCK_METHOD1(sendInternal, void(std::vector<uint8_t> data));
};
MATCHER_P2(HasBytes, bytes, size, "") {
// unnecessary assignment, I think ...
uint8_t * dataToCheck = arg;
bool isMatch = (memcmp(dataToCheck, bytes, size) == 0);
return isMatch;
}
using ::testing::ElementsAre;
TEST(xxx, yyy) {
ServerFake* serverFake = new ServerFake;
ServerFake2* serverFake2 = new ServerFake2;
uint8_t expectedMessageData[3] = { 0x08, 0xda, 0xff };
std::vector<uint8_t> expectedMessageData2({ 0x08, 0xda, 0xff });
EXPECT_CALL(*serverFake, sendInternal(HasBytes(expectedMessageData, 3), 3)).Times(1);
// the code below compiles and passes as well! However, I didn't check why;
// EXPECT_CALL(*serverFake, sendInternal(testing::_,3))
// .With(testing::Args<0, 1>(ElementsAre(0x08, 0xda, 0xff)))
// .Times(1);
serverFake->sendInternal(expectedMessageData, 3);
// much better, do like this!
EXPECT_CALL(*serverFake2, sendInternal(ElementsAre(0x08, 0xda, 0xff))).Times(1);
serverFake2->sendInternal(expectedMessageData2);
delete serverFake;
delete serverFake2;
}
Second, ElementsAre
officially does not support C-style arrays, according to this topic. If you really cannot change your method signature, and you really wish to use ElementsAre
on your raw array, you can use the hack proposed in that topic. Cheers.