gmock 多个模拟实例,但只有一个有效

gmock Multiple mock instances, but only one is effective

我想测试一个 class (Controller) 来管理一组特定类型的实体。实体是在这个 class 内部创建的,因为在这里工厂会有点矫枉过正,所以这是我向其中注入模拟的方式:

class TestController : public Controller {
public:
    /* Mechanism for a mock injection */
    std::shared_ptr<IEntity> create_entity() override {
        return temp_entity;
    }

    /* Variable to hold the entity being injected */
    std::shared_ptr<IEntity> temp_entity;
};

生产代码调用 create_entity()Controller class,我在这里重载,并将结果添加到容器中。 temp_entity 是我提供模拟和测试的方式,其中我提供两个不同的模拟实例,如下所示:

class MockEntity : public IEntity {
    MOCK_METHOD0(perform_operation, bool());
}

TEST(ControllerTest, TestFailure) {
    std::shared_ptr<TestController> controller = std::make_shared<TestController>();

    std::shared_ptr<MockEntity> entity1 = std::make_shared<MockEntity>();
    controller->temp_entity = entity1;
    controller->add_entity(); // This invokation fetches the result of create_entity()

    std::shared_ptr<MockEntity> entity2 = std::make_shared<MockEntity>();
    controller->temp_entity = entity2;
    controller->add_entity(); // This invokation fetches the result of create_entity()

    EXPECT_CALL(*entity1, perform_operation().WillOnce(::testing::Return(true));
    EXPECT_CALL(*entity2, perform_operation().WillOnce(::testing::Return(false));

    controller->run();
}

controller.run()只并发执行perform_operation () 在每个实体上。

当测试为运行时,第二个期望中的函数被调用了两次,而第一个期望中的函数根本不是运行。我确信控制器在 执行 运行() 函数之前对一个实体的两个不同版本进行操作。

我正在尝试做的事情是否存在根本问题?我如何在测试中区分对这两个模拟的期望?我尝试创建两个不同的模拟 classes,其中 perform_operation() 方法在模拟体中实现,当 运行在调试器中测试我仍然点击了一个模拟方法class两次。

测试看起来是正确的,将模拟注入被测系统的方式绝对合理。

我想,关键问题出在您的 class 测试中。我用以下控制器重建你的测试:

class Controller {
public:
    virtual std::shared_ptr<IEntity> create_entity() = 0;

    void add_entity() {
        auto entity = create_entity();
        entities.push_back(entity);
    }

    void run() {
        for(auto e : entities) {
            bool i =  e->perform_operation();
        }
    }
    std::vector<std::shared_ptr<IEntity> > entities;
};

有了这个 class 测试就如预期的那样成功了。