6

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?

2
  • EXPECT_CALL(API, doFoo(_)).Times(1); works? Commented Aug 27, 2015 at 13:25
  • @BЈовић That works as long as wrapper.foo() calls doFoo(), but I want to test to pass even if wrapper.foo() doesn't call doFoo(), as long as it calls doFooAndBar() instead. Commented Aug 27, 2015 at 13:27

1 Answer 1

3

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(); } 
Sign up to request clarification or add additional context in comments.

1 Comment

Partial order call looks like it could get out of hand quickly, but using the custom method executor seems like a suitable solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.