EXPECT_CALL().Times on "nested method call"

3,017 views
Skip to first unread message

Paul Hansen

unread,
Sep 26, 2011, 10:44:45 AM9/26/11
to Google C++ Mocking Framework
I want to check that a method calls another method.

class A
{
public:
void Inc() { IncOneStep(); IncOneStep(); } // public function to be
called
private:
void IncOneStep() { } // function that I want to check is actually
called by Inc()
};

class Mock_A : public A
{
MOCK_METHOD0(Inc, void(void));
MOCK_METHOD0(IncOneStep, void(void));
};

TEST(IncTest, OneStep)
{
Mock_A mock;
#ifdef USE_ON_CALL
A *p = &mock;
ON_CALL(mock, Inc()).WillByDefault(Invoke(p, &A::Inc));
#endif
EXPECT_CALL(mock, IncOneStep()).Times(AtLeast(1));
mock.Inc();
}

In the Google Mock For Dummies, there is the Turtle example with
Dependency Injection. But in the above I want to test that a method,
in the same class as the caller method, is actually called.
I understand that Mock_A::Inc() does not call Mock_A::IncOneStep().
If I #define USE_ON_CALL then A::IncOneStep() is called directly so
Mock_A::IncOneStep() is not called and again my expectation is not
met.

Can this be done?

Thank you very much
Paul

Keith Ray

unread,
Sep 29, 2011, 2:32:23 PM9/29/11
to Paul Hansen, Google C++ Mocking Framework
Declare IncOneStep() as "virtual" so it can be mocked correctly. You don't need the mock macros for Inc() since it isn't being mocked.

Some people call mocking parts of a concrete class a "partial mock".

Paul Hansen

unread,
Oct 6, 2011, 3:45:36 AM10/6/11
to Google C++ Mocking Framework
Thanks for you reply, Keith.
I have changed the code to:
class A
{
public:
A() {};
virtual ~A() {};
virtual void IncOneStep() {} // removed private for brevity
virtual void Inc() {IncOneStep(); IncOneStep(); }
};

class Mock_A : public A
{
public:
Mock_A() {};
virtual ~Mock_A() {};
MOCK_METHOD0(IncOneStep, void(void));
#ifdef USE_ON_CALL
MOCK_METHOD0(Inc, void(void));
#endif
};

TEST(A, IncTest)
{
Mock_A mock;
A *p = new A();
#ifdef USE_ON_CALL
ON_CALL(mock, Inc()).WillByDefault(Invoke(p, &A::Inc));
#endif
EXPECT_CALL(mock, IncOneStep()).Times(AtLeast(1));
mock.Inc();
delete p;
}

With #define USE_ON_CALL:
Inc() is called and IncOneStep() is called.
But gmock does not see that, the EXPECT_CALL does not pass.
A::IncOneStep() is called directly from A::Inc()
Without #define USE_ON_CALL:
mock.Inc() does not call mock.IncOneStep() so EXPECT_CALL fails.

Is it not possible to EXPECT_CALL between to methods of the same class
as above?
Or am I doing something wrong?

Thank you
Paul

Keith Ray

unread,
Oct 6, 2011, 4:11:39 PM10/6/11
to Paul Hansen, Google C++ Mocking Framework
try this... only mock ONE member function.

class A
{
public:
 A() {};
 virtual ~A() {};

 virtual void IncOneStep() {std::cout << "A::IncOneStep() called\n";}
 virtual void Inc() {std::cout << "A::Inc() called\n"; IncOneStep();
IncOneStep(); }
};

class Mock_A_IncOneStep : public A


{
public:
 Mock_A() {};
 virtual ~Mock_A() {};
 MOCK_METHOD0(IncOneStep, void(void));

};

TEST(A, IncTest)
{
 Mock_A_IncOneStep mock;


 A *p = new A();

 EXPECT_CALL(mock, IncOneStep()).Times(AtLeast(1));
 mock.Inc();
 delete p;
}


--
C. Keith Ray

Coach, Trainer, and Developer at Industrial logic, Inc.
http://industriallogic.com  "Amplify Your Agility"
Coaching and Live and Web-based Training

Vlad Losev

unread,
Oct 6, 2011, 5:31:12 PM10/6/11
to Google C++ Mocking Framework
On Thu, Oct 6, 2011 at 12:45 AM, Paul Hansen <paul.han...@gmail.com> wrote:
You instruct the mock to call Inc, but not on the instance that you expect it to be called on.
 
Thank you
Paul

Reply all
Reply to author
Forward
0 new messages