繁体   English   中英

如何在headerfiles中模拟函数?

[英]How to mock functions in headerfiles?

我在做什么:

我正在使用cmocka为大型嵌入式项目运行单元测试。 嵌入式项目使用arm-gcc-compiler 使用嵌入代码的片段和cmocka库,使用普通gcc编译单元测试。

通常cmocka建议使用-Wl -Wl,--wrap=functionName标志来模拟(替换)一些不需要的子函数。 这非常好用。

问题:

好吧,在我的嵌入式代码中有一个头文件( foo.h ),它包含一些函数(声明为内联)。 其中一个函数包含arm-gcc-compiler一些汇编代码,当然,它不能由gcc

愚蠢的是, wrap -flag似乎不适用于放在头文件中的函数。

题:

如何在头文件中模拟这个函数?

我是如何尝试解决问题的:

我想插入一些#idef宏来排除提到的汇编程序部分。 但是这不可能,因为该文件属于许可库,我不允许更改其内容。

我可以将我的测试功能提取到另外的文件中,这样就不再需要包含foo.h了。 但这会混淆嵌入式源代码结构。

确切的问题

确切的代码放在第233行的freeRtos的portmacro.h中:

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;

    __asm volatile
    (
        "   mov %0, %1                                              \n" \
        "   msr basepri, %0                                         \n" \
        "   isb                                                     \n" \
        "   dsb                                                     \n" \
        :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
    );
}

其中portFORCE_INLINE定义为:

#define portFORCE_INLINE inline __attribute__(( always_inline))

愚蠢的是,wrap-flag似乎不适用于放在头文件中的函数。

这不是wrap的错,函数已被编译器内联,因此链接器无法做到。

如何在头文件中模拟这个函数?

一种选择是使用sed在将其传递给gcc之前自动修补有问题的代码。 例如改变

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

从你的例子到

portFORCE_INLINE static void vPortRaiseBASEPRI( void );

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void );

cat tmp.c | sed '/inline\|INLINE/,/^}$/{ s/^\(.*\(inline\|INLINE\).*\)/\1;/; /inline\|INLINE/!d }'

正则表达式非常草率,它依赖于标题中的所有定义都将具有INLINE标记但在您的情况下应该足够的事实。

您可以将上面的命令嵌入到Makefile中,以在temp文件夹中生成自定义标头,然后使用-Ipath/to/temp/folder标志覆盖默认标头。

我没有使用cmocka所以我不确定是否有一种方法可以在框架内管理它。

但是, cmock使用一种方法,将标头复制到测试版本的包含层次结构中较高位置的位置(并且只有测试版本,即使发布版本也隐式包含该位置)。

然后可以编辑此标头的副本,使得函数声明只是变为port void vPortRaiseBASEPRI( void ); 然后,当生成模拟时,会为此生成模拟(以及同一标头内的其他函数声明),就像在任何其他情况下一样。 因为正在生成hte模拟,所以函数没有匹配的源代码定义(即.c文件)并不重要。

请参阅https://dmitryfrank.com/articles/unit_testing_embedded_c_applications上的“处理特定于编译器的内容”部分

我的类似问题以及我如何解决它: 使用编译器特定关键字对单元测试C进行单元测试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM