使用依赖注入并用 gmock 模拟它

Using dependency injection and mocking it with gmock

我在我的代码中实现了依赖注入模式。我这样做是为了能够使用 gmock 模拟服务。 DI 实现在生产代码中有效,但是,我在测试设置方面遇到了问题。使用 EXPECT_CALL 宏时,出现“表达式必须具有 class 类型”错误。我相信这与我设计依赖项的方式有关,但我找不到替代解决方案(缺乏经验)。我浏览过以前关于类似问题的主题,但 none 有所帮助。您能否看看下面的代码并提示可能的解决方法(使用 Car-Engine 接口的简化代码示例)?

// Engine interface class with pure virtual functions
class IEngine
{
public:
    virtual ~IEngine() = default;
    virtual void start() = 0;
    virtual void stop() = 0;
};


// A V8Engine class implementing this interface
class V8Engine : public IEngine
{
public:
    void start() override { std::cout << "V8 Engine started\n"; };
    void stop() override { std::cout << "V8 Engine stopped\n"; };
};


// Car.h file
class Car
{
public:
    Car(IEngine *engineService);
    void Drive();
private:
    IEngine* mEngine = nullptr;
};


// Car.cpp file
Car::Car(IEngine* engineService)
    : mEngine(engineService)
{
    if (mEngine == nullptr)
    {
        throw std::invalid_argument("service must not be null");
    }
}

void Car::Drive()
{
    mEngine->start();
    mEngine->stop();
}

我希望能够模拟引擎实现,而不是使用“真正的 V8Engine”,而是利用模拟。以下是我设置测试的方式:

class MockEngine : public IEngine
{
public:
    MOCK_METHOD(void, start, (), (override));
    MOCK_METHOD(void, stop, (), (override));
};

TEST(TestCarClass, TestCarWithMockEngine)
{
    IEngine *mockEngine = new MockEngine;
    Car carUnderTest(mockEngine);
    carUnderTest.Drive();

    EXPECT_CALL(mockEngine, start()); // This is the part where I get the error due to invalid mockEngine setup
}

EXPECT_CALL 期望 mock 对象作为第一个参数,您将引用传递给 mock。

要么使用 *mockPtr:

TEST(TestCarClass, TestCarWithMockEngine)
{
    IEngine *mockEngine = new MockEngine;
    Car carUnderTest(mockEngine);

    EXPECT_CALL(*mockEngine, start());

    carUnderTest.Drive();
}

或者直接避免分配:

TEST(TestCarClass, TestCarWithMockEngine)
{
    MockEngine mockEngine;
    Car carUnderTest(&mockEngine);

    EXPECT_CALL(mockEngine, start());

    carUnderTest.Drive();
}