Mock/Wrap static functions called by a non-static function under test
Asked Answered
K

2

1

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.

Kwangju answered 18/4, 2018 at 11:21 Comment(0)
B
4

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:

  1. 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).

  2. 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 #ifdefs:

    #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) {
       ... 
    }
    
  3. Use objcopy to globalize and weaken selected static functions, as explained in this answer.

Braze answered 18/4, 2018 at 13:32 Comment(1)
Thanks Groo. I've solved the problem by creating a separate layer (HAL). Now the functions are non static and I can mock them easily.Kwangju
P
2

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.

Phyfe answered 18/4, 2018 at 11:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.