cstaticmockingcmocka

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


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.


Solution

  • 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.