Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google mock - at least one of multiple expectations

I'm using Google Mock to specify a compatibility layer to an external API. In the external API, there are multiple ways to do some actions, so I want to specify that at least one (or preferably exactly one) expectation from a set of expectations are fulfilled. In pseudocode, this is what I want to do:

Expectation e1 = EXPECT_CALL(API, doFoo(...));
Expectation e2 = EXPECT_CALL(API, doFooAndBar(...));
EXPECT_ONE_OF(e1, e2);
wrapper.foo(...);

Is this possible to do using Google Mock?

like image 833
nemetroid Avatar asked Nov 10 '22 06:11

nemetroid


1 Answers

This is possible to do in two ways :

  1. with custom methods executor - create a class, with the same methods. And then use Invoke() to pass the call to that object
  2. using partial order call - create different expectations in different sequences, as explained here

With custom method executor

Something like this :

struct MethodsTracker {
   void doFoo( int ) {
     ++ n;
   }
   void doFooAndBar( int, int ) {
     ++ n;
   }
   int n;
};

TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
  MethodsTracker tracker;
  Api obj( mock );

  EXPECT_CALL( mock, doFoo(_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFoo ) );
  EXPECT_CALL( mock, doFooAndBar(_,_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFooAndBar ) );

  obj.executeCall();

  // at least one
  EXPECT_GE( tracker.n, 1 );
}

using partial order call

TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
      MethodsTracker tracker;
      Api obj( mock );

      Sequence s1, s2, s3, s4;

      EXPECT_CALL(mock, doFoo(_)).InSequence(s1).Times(AtLeast(1));
      EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s1).Times(AtLeast(0));

      EXPECT_CALL(mock, doFoo(_)).InSequence(s2).Times(AtLeast(0));
      EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s2).Times(AtLeast(1));

      EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s3).Times(AtLeast(0));
      EXPECT_CALL(mock, doFoo(_)).InSequence(s3).Times(AtLeast(1));

      EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s4).Times(AtLeast(1));
      EXPECT_CALL(mock, doFoo(_)).InSequence(s4).Times(AtLeast(0));

      obj.executeCall();
}
like image 199
BЈовић Avatar answered Nov 15 '22 12:11

BЈовић