Замена определения на "тестовое" определение в CppUTest

Возможно ли и, если возможно, каким образом заменить определенное определение определением, которое находится под контролем тестовой структуры?

Например, скажем, встроенная система использует определение для доступа к порту следующим образом:

#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))

Теперь я хочу убедиться, что мой "модуль порта" может правильно читать / писать в указанный PORTA_CONFIG. Как мне пойти на замену PORTA_CONFIG с чем-то вроде:

volatile unsigned int PORTA_CONFIG;

3 ответа

Для производственного кода вы используете:

//porta_config.h
...
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))

В то время как в вашем тестовом проекте вы используете другой заголовок:

//porta_config_test.h
...
volatile unsigned int PORTA_CONFIG;

Как и в ответе AudioDroid, вы можете использовать разные заголовки, включенные в один "заголовок фасада":

Подход включения (Test double)

portconfig.h заголовок для включения данных - в зависимости от того, какая цель вам нужна (или если вы используете ее для тестирования)

#ifndef PORTCONFIG_H
#define PORTCONFIG_H

#ifdef TARGET_A
# include <portconfig_target_a.h> /* Use the config for target A */
#elif defined TARGET_B
# include <portconfig_target_b.h> /* Use the config for target B */
#elif defined TEST
# include <portconfig_testing.h> /* Use this instead for testing */
#else
# error "Not supported!" /* Just in case ... */
#endif

#endif /* PORTCONFIG_H */

Каждый из этих заголовочных файлов содержит эти "определения", так как они требуются целью, например.

portconfig_target_a.h

...
#define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
...

или же

portconfig_testing.h

...
volatile unsigned int PORTA_CONFIG;
...

Это требует #ifdef только в одном центральном месте и поэтому требует меньших усилий по обслуживанию. Также нет никакой разницы в использовании целевого / тестового кода, #include <portconfig.h> используется во всех случаях.

Абстракция подход

Вместо того, чтобы использовать PORTA_CONFIG напрямую, вы также можете абстрагировать его в функцию / макрос. Для тестирования вы можете издеваться над этим.

typedef IOAddress ...
IOData IOData ...

void writePort(IOAddress addr, IOData data);
IOData readPort(IOAddress);

Это имеет преимущество абстракции и очень полезно для тестирования.

В этом репозитории есть реализация и несколько отличных примеров, особенно code (MockIO, заголовок, реализация, пример теста) - с использованием CppUTest.

Смотрите также

Если я правильно понимаю ваши намерения, вы можете сделать что-то вроде:

#define TESTING

int main(){
#ifdef TESTING
    volatile unsigned int PORTA_CONFIG;
#else
    #define PORTA_CONFIG (*(volatile unsigned int*) (0x1000))
#endif
Другие вопросы по тегам