Search code examples
c++testinggoogletestgooglemock

Use EXPECT_CALL on local object of function?


Is there a way to use EXPECT_CALL on a local object of a function?

For example:

template<class T>
std::string doSomethingWithTheCar()
{
    T car;
    return "the color of the car is: " + car.color();
}

class Car
{
public:
    std::string color()
    {
        return "green";
    }
};

class MockCar
{
public:
    MOCK_METHOD0(color, std::string());
};

TEST(MockLocalObject, doSomethingWithCarTest) {
    EXPECT_CALL(car, color())
        .WillOnce(Return("red"));

    std::string color = doSomethingWithTheCar<MockCar>();
    EXPECT_EQ(color, "red");
}

Due to the template I can control if the real Car object will be used or the MockCar. But is there a way to use EXPECT_CALL on this?


Solution

  • I would do it like this:

    class AbstractCar {
    public:
        virtual ~AbstractCar() = default;
        virtual std::string color() = 0;
    };
    
    class Car: public AbstractCar {
    public:
        ~Car() override = default;
        std::string color() override {
            return "green";
        }
    };
    
    class MockCar: public AbstractCar {
    public:
        MOCK_METHOD0(color, std::string());
    };
    
    std::string doSomethingWithTheCar(AbstractCar* car)  // or even better - use std::shared_ptr
    {
        return "the color of the car is: " + car->color();
    }
    
    TEST(MockLocalObject, doSomethingWithCarTest) {
        auto car = new MockCar;
        EXPECT_CALL(*car, color()).WillOnce(Return("red"));
    
        std::string color = doSomethingWithTheCar(car);
        // this test will fail, because actual string is:
        // "the color of the car is: red"
        EXPECT_EQ(color, "red");
        delete car;
    }