引用对我在 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;
};
我是 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;
};