C Модульный тест: заглушка постоянной структуры (г cc - обертка) - PullRequest
0 голосов
/ 24 марта 2020

Привет Все, вот мой конкретный c чехол:

service.h:

    typedef struct {
        uint8_t (*function1)(void);
        uint8_t (*function2)(void);
    } const service_struct_t;

    extern service_struct_t service_api ;

service. c:

    #include "service.h"

    static uint8_t foo(void){
         return 13+6;
    }
    static uint8_t bar(void){
         return 7*6;
    }

    service_struct_t service_api = {
        .function1 = foo,
        .function2 = bar,
    };

Мне нужно заглушки (насмехаться, заменять) эти функции, но я не имею права изменять исходный код. Я использую g cc для компиляции модульных тестов. Мне не удалось:

  • использовать параметр --wrap для g cc прямо на foo и bar, поскольку они находятся c для источника. c:

    #include "service.h"
    #define ENABLE_STUB 1 /* that is actually a variable toggled at runtime */
    uint8_t __real_foo(void);
    uint8_t __wrap_foo(void){
        if(ENABLE_STUB){
            return 1;
        }else{
            return __real_foo();
        }
    }
    /* same for bar */

  • используйте параметр --wrap g cc для символа объекта service_api, поскольку он не является функцией

    #include "service.h"
    #define ENABLE_STUB 1 /* that is actually a variable toggled at runtime */
    uint8_t __real_service_api ;
    uint8_t __wrap_service_api = {
        .function1 = foo,
        .function2 = bar,
    }

    static uint8_t foo(void){
        if(ENABLE_STUB){
            return 1;
        }else{
            return __real_service_api.function1();
        }
    }
    /* same for bar */

  • просто переназначить функции-члены service_api, поскольку структура постоянна и уже назначена.

    #include "service.h"
    #define ENABLE_STUB 1 /* that is actually a variable toggled at runtime */
    service_struct_t backup_service_api = {
        .function1 = service_api.function1;
        .function2 = service_api.function2;
    }
    service_struct_t stub_service_api = {
        .function1 = foo;
        .function2 = bar;
    }

    uint8_t foo(void){
        if(ENABLE_STUB){
            return 1;
        }else{
            return __real_foo();
        }
    }/* same for bar */

    void service_poke_stub(bool_t enable_stubs){
        if(enable_stubs){
            service_api.function1 = stub_service_api.function1
            service_api.function2 = stub_service_api.function2
        }else{
            service_api.function1 = backup_service_api.function1
            service_api.function2 = backup_service_api.function2
        }
    }

спасибо уже за вашу помощь

1 Ответ

1 голос
/ 24 марта 2020

Вы не можете смоделировать функции в структуре, как вы уже узнали.

Так что это зависит от , что вы хотите проверить :

  • Если вы хотите проверить, содержит ли структура правильные функции, модуль service.c является вашим тестируемым модулем и должен использоваться как есть. Вам необходимо проверить правильность, наблюдая за тем, что делают функции.

  • Если вы хотите проверить, правильно ли используется структура, вы будете издеваться над всем модулем. Теперь вы можете добавлять в нее все, что захотите.

Если ваш исходный код не позволяет этого, дизайн плох для тестирования. Это часто бывает, когда архитектура не выполнена с учетом тестируемости.

...