c++googletestgooglemock

Make one EXPECT_CALL unsequenced


I have a set of calls which I want to check in order, but they may be arbitrarily interspersed with a call to a log method. How can I tell gmock that that particular method can be called any number of times?

Partial ordering with a InSequence(...) on each expect is not feasible because real test has many more EXPECT_CALLs, many set in multiples in helpers methods I cannot easily modify. Neither is repeating the EXPECT_CALL(mock, log)... between any other expect.

It appears that the InSequence object applies to all expects, even if I try to override one of them with an InSequence(...) call.

#include <gtest/gtest.h>
#include <gmock/gmock.h>
 
class my_mock {
    public:
    MOCK_METHOD(void, foo, ());
    MOCK_METHOD(void, bar, ());
    MOCK_METHOD(void, baz, ());
    MOCK_METHOD(void, log, ());
};
 
class my_test : public testing::TestWithParam<uint32_t> {};
 
void test(my_mock& mock, uint32_t mask) {
    if (mask & 1) mock.log();
    mock.foo();
    if (mask & 2) mock.log();
    mock.bar();
    if (mask & 4) mock.log();
    mock.baz();
    if (mask & 8) mock.log();
}
 
TEST_P(my_test, my_test) {
    testing::StrictMock<my_mock> mock{};
    testing::InSequence seq{};
    testing::Sequence unseq{};
 
    EXPECT_CALL(mock, log).Times(testing::AnyNumber()).InSequence(unseq);
    EXPECT_CALL(mock, foo).Times(1);
    EXPECT_CALL(mock, bar).Times(1);
    EXPECT_CALL(mock, baz).Times(1);
 
    test(mock, GetParam());
}
 
INSTANTIATE_TEST_SUITE_P(
    my_test, my_test, testing::Range<uint32_t>(0, 16)
);

https://godbolt.org/z/jKj3G6rT6


Solution

  • Group the sequence in a scope:

    TEST_P(my_test, my_test) {
        testing::StrictMock<my_mock> mock{};
    
        EXPECT_CALL(mock, log).Times(testing::AnyNumber());
        {
            testing::InSequence seq{};
            EXPECT_CALL(mock, foo).Times(1);
            EXPECT_CALL(mock, bar).Times(1);
            EXPECT_CALL(mock, baz).Times(1);
        }
        test(mock, GetParam());
    }
    

    Demo