引用对我在 TDD 中的模拟来说是一种痛苦

references are a pain for my mocks in TDD

我是 c++/tdd 的新手,拥抱了 gtest/gmock,并坠入爱河。 不过有一件事让我感到困惑。引用指针真的可行吗?

我发现自己制作了很多注入所有模拟的样板(即使我没有任何业务模拟 那个 行为)。

示例:

namespace
{
    class set_configuration_command_tests : public testing::Test
    {
        protected:

        void SetUp() override
        {
            _uart_peripheral = new uart8_peripheral_mock();
            _uart = new uart8_mock(*_uart_peripheral);
            _logger =  new logger_mock(*_uart);
            _mqtt_client = new mqtt_client_mock(*_logger);
            _set_configuration_command = new set_configuration_command(*_mqtt_cient);
        }

        void TearDown() override
        {
            delete _set_configuration_command;
        }

        uart8_peripheral_mock *_uart_peripheral;
        uart8_mock *_uart;
        logger_mock *_logger;
        mqtt_client_mock *_mqtt_cient;

        set_configuration_command *_set_configuration_command;
    };

    TEST_F(set_configuration_command_tests, execute_update_configuration)
    {
        // arrange
        // act
        // assert
    }
}

我宁愿在这里做的是将我的 sut 创建为

_mqtt_client = new mqtt_client_mock(nullptr); // will not compile of course
_set_configuration_command = new set_configuration_command(*_mqtt_cient);

所有其他模拟,在这种情况下我不需要。

这是使用引用指针的缺点吗?或者我应该遵循更好的方法吗?

找到更好的选择。提供接口(纯虚拟 classes)大大减少了提供整个模拟树的需要。

例如

class flash_api : public iflash_api
{
    public:
    flash_api(iflash_peripheral &flash_peripheral) : _flash_peripheral(flash_peripheral)
    {
    }

    virtual ~flash_api()
    {
    }
}

之前我的 mock 直接继承自 flash_api。当我也给这个 class 一个接口(`iflash_api')时,我可以让我的模拟继承自 iflash_api,这给了我一个无参数的构造函数。

class flash_api_mock : public iflash_api
{
    public:
    flash_api_mock()
    {
    }

    virtual ~flash_api_mock()
    {
    }
}

然后我可以根据我实际想要提供行为的模拟编写我的单元测试。

class set_configuration_command_tests : public testing::Test
{
    protected:

    void SetUp() override
    {
        _mqtt_cient = new mqtt_client_mock();
        _flash_api = new flash_api_mock();
        _set_configuration_command = new set_configuration_command(*_mqtt_cient, *_flash_api);
    }

    void TearDown() override
    {
        delete _set_configuration_command;
    }

    flash_api_mock *_flash_api;
    mqtt_client_mock *_mqtt_cient;

    set_configuration_command *_set_configuration_command;
};