4

I am using mocka to unit test a C project.

I want to mock a call to another modules made in my C function under test. This function in the other module deals with doubles, not ints. The will_return documentation says it passes integer values, and I can see that if I call will_return(__wrap_other_func, 42.99) then the value passed into __wrap_other_func and pulled out through double value = mock_type(double) will be 42.0, not the desired 42.99.

double __wrap_other_func(double param) {
  check_expected(param);
  double value = mock_type(double); // will_return() has converted this, effectively rounding
  fprintf(stderr, "%lf\n", value);
  return value;
}

static void test_this_func(void **state) {
  (void) state;
  expect_value(__wrap_other_func, param, 1.0);
  will_return(__wrap_other_func, 42.99);
  int result = this_func(12.34); // this_func() will call other_func()
  ...
  assert(result == 0); 
  /* the assert is failing because the double 42.99 is converted to an integer,
     then back to a double, rounding off all the decimal places. */
}

> 42.0

Has anyone figured out how to pass doubles into the mock function with will_return or some other cmocka method? I'm stuck on this.

I was expecting to be able to pass non-integer values to my mock function using cmocka.

When I tried that using will_return(), I found all double values were rounded to integer equivalents.

I have pored over the cmocka documentation and searched for cmocka examples online.

Tom Willis
  • 306
  • 4
  • 10
  • 1
    I'm not an expert when it comes to cmocka or any other c unit test library for that matter, but I think there's good reason for cmocka to not allow `double` to be passed to `will_return` because comparing doubles is not really a good idea because of precision. How about changing the function to return an integer instead that represents a fraction of something? This is how it is generally worked around in embedded systems where floating point operations are costly. You could still expose the `double` function with a simple conversion between the two. – Marco Jan 23 '23 at 05:58
  • Thank you for the comment, Marco! In this case, the wrapped function performs a calculation on doubles, so changing its type and signature for mocking does not seem right. Precision on the doubles can be managed in the test code. – Tom Willis Jan 23 '23 at 18:27
  • How Marco suggests, cast the value to int (keeping the same byte size) before calling `will_return()`, then inside your function you cast it back to its original type. – mEm Jan 31 '23 at 16:36

1 Answers1

0

The intended way is to use will_return_float and mock_float

There are also other "assigning" macros:

  • will_return_int mock_int
  • will_return_float mock_float
  • will_return_ptr mock_ptr
  • etc.

to use instead of the "casting" macros will_return and mock_type

Side note: mock_float doesn't take macro arguments, as of now it stores the value as a double

Pignotto
  • 555
  • 3
  • 11