I'm trying to test two serial port write+read calls. The first one has to block on read
for 101ms and thus cause a timeout error. The second one should run fine. Based on the google mock manual the InSequence
variable should ensure that. Here is the code:
{
// This variable ensures the sequence order
InSequence s;
EXPECT_CALL(serial_, Write(_, _))
.With(ElementsAreArray(command1_))
.WillOnce(Invoke(Write));
EXPECT_CALL(serial_, Read(_, _, _))
.WillOnce(Invoke(TimeoutRead));
EXPECT_CALL(serial_, Write(_, _))
.With(ElementsAreArray(command2_))
.WillOnce(Invoke(Write));
EXPECT_CALL(serial_, Read(_, _, _))
.Times(1)
.WillOnce(DoAll(SetArrayArgument<0>(response_begin, response_end),
SetArgumentPointee<2>(response_.size()),
Return(true)));
}
TimeoutRead
is just a function that causes current thread to sleep for 101ms.
However, I keep getting this runtime error:
[ RUN ] MasterTest.LostReply
/host/Users/blah/work/bitbucket/master_test.cc:631: Failure
Mock function called more times than expected - returning default value.
Function call: Read(0x5652c3f31120 pointing to "\xFF\xFF", 4096, 0x7ffda19d2960)
Returns: false
Expected: to be called once
Actual: called twice - over-saturated and active
It seems that GTest is trying to call the last EXPECT_CALL
designed for the second read
.
Is there a way to enforce this sequence of calls?
[THIS IS TEMPORARY EDIT TO PRESENT SSCCE YOU NEED TO PROVIDE TO GET ANSWER]
This is SSCCE I expect you update appropriately to get error you are mentioning in your question. The code below works and passes:
class Serial_
{
public:
MOCK_METHOD2(Write, void(int* elems, size_t n));
MOCK_METHOD3(Read, bool(int* elems, int dummy, size_t* n));
};
int command1_[] = {1,2,3};
int command2_[] = {4,5};
std::array<int, 4> response_{{ 6, 7, 8, 9 }};
void testScenario(Serial_& serial_)
{
int dummy_arr[100];
size_t dummy_size;
serial_.Write(command1_, 3);
serial_.Read(dummy_arr, 123, &dummy_size);
serial_.Write(command2_, 2);
serial_.Read(dummy_arr, 123, &dummy_size);
}
bool TimeoutRead(int* elems, int dummy, size_t* n)
{
return true;
}
void Write(int* elems, size_t n)
{}
TEST(A,A)
{
Serial_ serial_;
// This variable ensures the sequence order
InSequence s;
EXPECT_CALL(serial_, Write(_, _))
.With(ElementsAreArray(command1_))
.WillOnce(Invoke(Write));
EXPECT_CALL(serial_, Read(_, _, _))
.WillOnce(Invoke(TimeoutRead));
EXPECT_CALL(serial_, Write(_, _))
.With(ElementsAreArray(command2_))
.WillOnce(Invoke(Write));
EXPECT_CALL(serial_, Read(_, _, _))
.Times(1)
.WillOnce(DoAll(SetArrayArgument<0>(response_.begin(), response_.end()),
SetArgumentPointee<2>(response_.size()),
Return(true)));
testScenario(serial_);
}
With(ElementsAreArray(command2_))
constraint to second Write happens or not. Or - just check if second write happens. E.g. remove all ElementsAreArray checks... ? – Metrorrhagiawrite
will cause the secondEXPECT_CALL(Read)
to be matched twice? It seems to me that the sequence requirement isn't working. – Bulldozeserial_
mock definition and the best would be sscce.org – MetrorrhagiaTimeoutRead
hasstd::this_thread::sleep_for(11ms)
in it to cause the wrapper of theserial_
mock functions to timeout and fail. – Bulldoze