I am using cmocka 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.
Update 2023-11-19 I have a solution.
The cmocka
main repo at cryptomilk was updated by Andreas Schneider so that mocks work with real numbers (floats and doubles) as expected.
Thank you Andreas!
With the 2023-11-17 head of the main branch built and installed on my system, this code now works as expected.
double __wrap_other_func(double param) {
// verify that the expected value was passed in to the mock
check_expected(param);
// assign the return value
double value = mock_float;
// will_return_float() can deal with real numbers (doubles and floats)
fprintf(stderr, "%lf\n", value); // this will print the real number value now
return value;
}
static void test_this_func(void **state) {
(void) state;
// make sure the argument passed to the mock is correct
expect_value(__wrap_other_func, param, 1.0);
// tell the mock what to return
will_return_float(__wrap_other_func, 42.99);
// call this_func normally. The mock for other_func will get called
int result = this_func(12.34); // this_func() will call other_func()
...
assert(result == 0);
// the assert is now passing because the double 42.99 remains a double
}
> 42.99
Thanks to everyone who offered comments and answers.
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
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