Search code examples
c++unit-testinggoogletestgooglemock

Multiple prerequisites in partially ordered mock calls in googletest


I was reading partially ordered calls for googletest here and I understoond how their example works. So we can use:

using ::testing::Sequence;
...
  Sequence s1, s2;

  EXPECT_CALL(foo, A())
      .InSequence(s1, s2);
  EXPECT_CALL(bar, B())
      .InSequence(s1);
  EXPECT_CALL(bar, C())
      .InSequence(s2);
  EXPECT_CALL(foo, D())
      .InSequence(s2);

to show the following DAG:

       +---> B
       |
  A ---|
       |
       +---> C ---> D

But I wondered how we can define multiple prerequisites of a call. For example, how I can add DAG constraints for E node in following DAG?

       +---> B ----------+
       |                 |
  A ---|                 |---> E
       |                 |
       +---> C ---> D ---+

Will it be something like this?

using ::testing::Sequence;
...
  Sequence s1, s2, s3;

  EXPECT_CALL(foo, A())
      .InSequence(s1, s2);
  EXPECT_CALL(bar, B())
      .InSequence(s1, s3);
  EXPECT_CALL(bar, C())
      .InSequence(s2);
  EXPECT_CALL(foo, D())
      .InSequence(s2, s3);
  EXPECT_CALL(foo, E())
      .InSequence(s3);

Solution

  • You can use After method to expect some call after certain other call(s). https://google.github.io/googletest/reference/mocking.html#EXPECT_CALL.After

    So in your case it will be like this:

    Mocked mock;
    Sequence s1, s2;
    EXPECT_CALL(mock, A).InSequence(s1, s2);
    Expectation exp_b = EXPECT_CALL(mock, B).InSequence(s1);
    EXPECT_CALL(mock, C).InSequence(s2);
    Expectation exp_d = EXPECT_CALL(mock, D).InSequence(s2);
    EXPECT_CALL(mock, E).After(exp_b, exp_d);
    

    Full runnable example:

    #include <gmock/gmock.h>
    #include <gtest/gtest.h>
    
    using ::testing::Sequence;
    using ::testing::Expectation;
    
    class Mocked {
    public:
        MOCK_METHOD(void, A, ());
        MOCK_METHOD(void, B, ());
        MOCK_METHOD(void, C, ());
        MOCK_METHOD(void, D, ());
        MOCK_METHOD(void, E, ());
    };
    
    TEST(Sequences, ABCDE)
    {
        Mocked mock;
        Sequence s1, s2;
        EXPECT_CALL(mock, A).InSequence(s1, s2);
        Expectation exp_b = EXPECT_CALL(mock, B).InSequence(s1);
        EXPECT_CALL(mock, C).InSequence(s2);
        Expectation exp_d = EXPECT_CALL(mock, D).InSequence(s2);
        EXPECT_CALL(mock, E).After(exp_b, exp_d);
    
        mock.A();
        mock.B();
        mock.C();
        mock.D();
        mock.E();
    }
    

    P.S. You can completely replace InSequence with After to have a little bit simpler code.