Reputation: 409
I would like to test some functions by implementing unit tests with cmocka framework.
For example I have a non-static function under test which calls two static functions. Because of the fact that these static functions interact with hardware I want to mock/wrap them and use a wrap function instead of the real function when testing.
Like described in the cmocka documentation I've used the --wrap=myfunction linker flags when building/linking my tests.
The tests compile but when I run them the real static functions will be called instead of the wraps.
When I declare the static functions non-static it doesn't work either and also the real functions are called. The only solution I've found is to outsource the functions in an extra .c-file...but that's a really bad workaround because it manipulates the code very much.
Upvotes: 1
Views: 2572
Reputation: 51274
As @Paul wrote, this is simply how --wrap
works, the functions need to be in a different compilation unit if you want gcc to wrap them. Generally, static methods are private implementation details which you don't want to expose for testing.
So to add some more options to the other answer:
Obviously, the simplest way to mock these functions without polluting the original code with conditionals is to extract them into a separate layer (in this case, a HAL).
You can make the static
modifier conditional, which will allow wrapping with cmocka. This does less polluting to the original code than a bunch of #ifdef
s:
#ifndef UNIT_TESTING
# define mockable_static static
#else
# define mockable_static
#endif
// then, replace 'static' with 'mockable_static'
mockable_static void some_static_method(void) {
...
}
Use objcopy to globalize and weaken selected static functions, as explained in this answer.
Upvotes: 4
Reputation: 25286
If you have a .c file with a public function and two static functions, and the public function calls the static functions, then you cannot prevent the static functions being called. After all, they are one compilation unit.
You can:
test them as a whole
use #ifdef
conditional compilation to replace the static functions with simplified, non-hardware calling static functions to test the public function
use #ifdef
conditional compilation to replace the public function with a specialised public function to test the static functions.
Upvotes: 2