Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use gmock to test that a class calls it's base class' methods

class Foo {
public:
    int x;
    int y;

    void move(void);
};

class SuperFoo: public Foo {
public:
    int age;

    void update();
};

SuperFoo::update(void) {
    move();
    age++;
}

I'm just starting out with C++ and unit testing, I have some code resembling the above and I want to use gmock to test that SuperFoo::update() calls the base class' move() method. What would be that best way to attack this type of situation?

like image 754
Dasaan Avatar asked Aug 25 '14 13:08

Dasaan


People also ask

How do you mock in gMock?

first, you use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; next, you create some mock objects and specify its expectations and behavior using an intuitive syntax; then you exercise code that uses the mock objects.

What is the difference between gMock and Gtest?

Gtest is a framework for unit testing. Gmock is a framework imitating the rest of your system during unit tests. Show activity on this post. Suppose you're writing a piece of code that needs to interact with an unpredictable, expensive, external system (e.g. a Web site, a large database, a physical sensor, etc.)

What is expect call in gMock?

In gMock we use the EXPECT_CALL() macro to set an expectation on a mock method. The general syntax is: EXPECT_CALL(mock_object, method(matchers)) . Times(cardinality) .


1 Answers

One way is to make the move method virtual, and create a mock of your class:

#include "gtest/gtest.h"
#include "gmock/gmock.h"

class Foo {
public:
    int x;
    int y;

    virtual void move(void);
    //^^^^ following works for virtual methods
};
// ...

class TestableSuperFoo : public SuperFoo
{
public:
  TestableSuperFoo();

  MOCK_METHOD0(move, void ());

  void doMove()
  {
    SuperFoo::move();
  }
};

Then in your test, setup the corresponding call expectations

TEST(SuperFoo, TestUpdate)
{
  TestableSuperFoo instance;

  // Setup expectations:
  // 1) number of times (Times(AtLeast(1)), or Times(1), or ...
  // 2) behavior: calling base class "move" (not just mock's) if "move" 
  //    has side-effects required by "update"
  EXPECT_CALL(instance, move()).Times(testing::AtLeast(1))
    .WillRepeatedly(testing::InvokeWithoutArgs(&instance, &TestableSuperFoo::doMove));

  const int someValue = 42;
  instance.age = someValue;
  // Act
  instance.update();
  // Assert
  EXPECT_EQ(someValue+1, instance.age);
}
like image 57
SleuthEye Avatar answered Sep 29 '22 10:09

SleuthEye