Rajeev Mehta
Rajeev Mehta

Reputation: 659

Googlemock Pause Expectations

I have a scenario where I expect some calls on a function on the mock object, and then for certain code path I need to ensure that function is not called, and after that, it is called. Is there any way to do this?

EXPECT_CALL(mockObj, 1); 
foo(1);

// Expect this call at the first invocation of foo(2)
EXPECT_CALL(mockObj, 2); 
foo(2);

// These calls should not call my mockObj again, the above expectation is 
// intended for the first invocation of foo(2)
foo(2);
foo(2);

// And now, i expect it to be called
EXPECT_CALL(mockObj, 3); 
foo(3);

I could may be check that EXPECT_CALL(mockObj, 2); is called only the expected number of times, But i also want to confirm that it is called only at the first call to foo(2) and not at the subsequent calls to foo(2). Can you please let me know of any way to achieve this in gmock?

Upvotes: 1

Views: 485

Answers (3)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38538

Do you want getting something like this?

EXPECT_CALL(mockObj, 1).Times(0);
EXPECT_CALL(mockObj, 2).Times(0); // #2
EXPECT_CALL(mockObj, 3); // #3

{
  EXPECT_CALL(mockObj, 1); // #1
  foo(1); // Matches #1
}

{
  EXPECT_CALL(mockObj, 2); // #4
  // Expect this call at the first invocation of foo(2)
  foo(2); // Matches #4
}

// These calls should not call my mockObj again, the above expectation is 
// intended for the first invocation of foo(2)
foo(2); // Matches #2
foo(2); // Matches #2

// And now, i expect it to be called
foo(3); // Matches #3

Upvotes: 0

Ian Martin
Ian Martin

Reputation: 41

Gmock cookbook suggests using a dummy checkpoint mock function

using ::testing::MockFunction;

TEST(FooTest, InvokesMyMockCorrectly) {
  MyMock mockObj;
  // Class MockFunction<F> has exactly one mock method.  It is named
  // Call() and has type F.
  MockFunction<void(string check_point_name)> check;
  {
    InSequence s;

    EXPECT_CALL(mockObj, 1);
    EXPECT_CALL(check, "1");
    EXPECT_CALL(mockObj, 2);
    EXPECT_CALL(check, "2");
    EXPECT_CALL(check, "3");
    EXPECT_CALL(mockObj, 3);
  }
  
  foo(1);
  check.Call("1");

  foo(2);
  check.Call("2");

  foo(2);
  foo(2);

  check.Call("3");
  foo(3);
}

Or use Mock::VerifyAndClearExpectations() to reset the mock and then set new expectations.

Otherwise interleaving calls to a mock and EXPECT_CALLs as suggested in some answers is undefined behaviour:

Important note: gMock requires expectations to be set before the mock functions are called, otherwise the behavior is undefined. In particular, you mustn't interleave EXPECT_CALL()s and calls to the mock functions.

From gmock for dummies, also see Interleaving EXPECT_CALL()s and calls to the mock functions

Upvotes: 3

Georg P.
Georg P.

Reputation: 3164

I would split it into several test cases:

TEST(Foo, CalledOnFirstInvoation) {
  EXPECT_CALL(mockObj, 1); 
  foo(1);
}

TEST(Foo, CalledAgainWhenUsingDifferenArgument) {
  EXPECT_CALL(mockObj, 2); 
  foo(1);
  foo(2);
}

TEST(Foo, NotCalledWhenUsingSameArgument) {
  EXPECT_CALL(mockObj, 2); 
  foo(1);
  foo(2);
  foo(2);
  foo(2);
}

TEST(Foo, CalledAgainWhenUsingYetAnotherArgument) {
  EXPECT_CALL(mockObj, 3); 
  foo(1);
  foo(2);
  foo(2);
  foo(3);
}

Upvotes: 2

Related Questions