В настоящее время я разрабатываю некоторые драйверы низкого уровня для встроенной платформы в обычном C. Я использую единицу + cmock как единую тестовую платформу.Дубликат кода между модульным тестом и его реализацией
Однако при написании материала низкого уровня, я часто сталкиваюсь со следующей схемой:
Тест:
void test_mcp2515_read_register(void)
{
spi_frame_t expected_frame = {{0}};
expected_frame.tx_length = 2;
expected_frame.rx_length = 3;
expected_frame.tx_data[0] = MCP2515_READ_CMD;
expected_frame.tx_data[1] = TEST_ADDR;
expected_frame.callback = callback_test;
spi_transmit_ExpectAndReturn(expected_frame, true);
mcp2515_read_register(TEST_ADDR, callback_test);
}
Реализация:
void mcp2515_read_register(uint8_t addr, spi_callback callback)
{
spi_frame_t frame = {{0}};
frame.tx_length = 2;
frame.rx_length = 3;
frame.tx_data[0] = MCP2515_READ_CMD;
frame.tx_data[1] = addr;
frame.callback = callback;
spi_transmit(frame);
}
Как вы можете видеть, что есть много дублирование между кодом между тестом и реализацией.
Это проблема? Я пишу свои тесты неправильно? Или мне не нужно вообще писать тесты на этот материал низкого уровня?
Это почти точно, как создается приложение. Функция обратного вызова необходима, когда выполняется передача (async) SPI. Таким образом, spi_frame_t не зависит от реализации SPI и используется только для указания того, какие данные должны быть переданы. Мой первоначальный вопрос по-прежнему не ответил. Как я могу избежать дублирования кода между тестом и реализацией. Если моя реализация составляет почти 90% копии/вставки из моего теста, какое использование имеет тест. –
@WillemMelching Если кадр SPI не имеет ничего общего с SPI, почему вы назвали его префиксом SPI? Либо вы задали тип запутанного имени, либо ваш код контроллера CAN выполняет то, о чем он не должен относиться. – Lundin
@WillemMelching Во всяком случае, на самом деле не имеет значения, где находится фрейм SPI, потому что вы все еще можете выполнить реализацию с непрозрачным типом и конструктором. Таким образом, создание кадра отделено от передачи, и ваш тестовый код может вызывать конструктор кадра так же, как и функцию производственного кода. Ваше приложение не делает этого, вы используете простые «процедурные структуры программирования», где ваш код приложения тесно связан с типом данных структуры. И поэтому вам нужно повторить код в тестовом примере. – Lundin