cunit-testinggccstaticcmocka

How to handle static elements with cmocka?


I am using cmocka to do some unit testing on my C-Project and I am wondering how to handle static emelents.

Static elements are for me:

  1. Functions declared as static
  2. Variables inside functions which are declared as static

So let the function fut be our function under test, and foo be an other function. Both placed in the file bar.c:

static int fut(int add) {
  static int sum = 0;
  sum += add;
  return sum;
} 

int foo(int someVar){
  //Some calculation on someVar...
  someVar = someVar * 42;

  //call subRoutine
  return fut(someVar);
 }

And let foo.h look like this:

extern int foo(int someVar);

So lets go on I'll show the problem. I would like to test the function under test by two undepended tests which pass some random values for add. The testroutines are placed in main.c and are looking like this:

void fut_test_1(void **state) {
  int ret;
  ret = fut(15);
  assert_int_equal(ret, 15);
  ret = fut(21);
  assert_int_equal(ret, 36);
}

void fut_test_2(void **state) {
  int ret;
  ret = fut(32);
  assert_int_equal(ret, 32);
  ret = fut(17);
  assert_int_equal(ret, 49);
}

Now I could try to compile the unit test with something like: gcc main.c foo.c -Icmocka

There are now two problems:

  1. The function declared as static cannot be accessed from main.c, so the linker will stop during the build process.

  2. The variable inside the function which are declared as static will not be reset between the two tests. So the fut_test_2 will fail.

How to handle these problems with the mentioned static elements?


Solution

  • Based on @LPs comment and my own ideas I would like to conclude possible solutions:

    Regarding the Problem one with Functions declared as static:

    1. One solution would be to include the source file bar.c into the test driving main.c by #include "foo.c".
    2. The tests fut_test_2 and fut_test_2 could by placed into bar.c which contains then both: The function under test fut and the tests. The tests can then be made accessible by adding the declaration to foo.h:

      extern int foo(int someVar);
      extern void fut_test_1(void **state);
      extern void fut_test_2(void **state);
      

    Regarding the Problem with the static variables:

    1. This is not easy for testing. The only possibility is to enlarge the visibility of the the static variable by one of the fallowing ways:
      • by moving it outside of the fut
      • make it globally
      • use some getter and setter methods
    2. Write only functions which do not need static variables to be reseted during the testing process.