meekrosoft / fff

A testing micro framework for creating function test doubles
Other
761 stars 167 forks source link

document return_val is ignored when custom_fake is defined #56

Open trombik opened 6 years ago

trombik commented 6 years ago

return_val is ignored when custom_fake is defined, but that fact is not well-documented.

suppose you are going to test set_pin_direction() function, which calls a fake function read8() that is supposed to read a value from an I2C slave. set_pin_direction() returns 0 when read8() has failed for whatever reason. you would like to test the function without slave IC.

first, fakeread8() in the test.

FAKE_VALUE_FUNC(int32_t, read8,  const uint8_t, uint8_t *);

next, create a custom fake function that returns a faked register value.

static uint8_t faked_reg_value; // a global variable to set faked values in tests

void * read8_fake_custom_fake(const uint8_t reg, uint8_t *reg_value)
{
        *reg_value = faked_reg_value;
}

and the actual test.

TEST_CASE("my_test_1", component)
{
        faked_reg_value = 0xff;
        read8_fake.custom_fake = read8_fake_custom_fake;
        read8_fake.return_val = 0;
        r = set_pin_direction(1, OUTPUT);
        TEST_ASSERT_EQUAL_UINT32(0, r);
}

you expects read8() returns 0, and the passed pointer contains 0xff as value.

the above test will NOT work. because the expanded macros contains the following definition.

if (read8_fake.custom_fake) return read8_fake.custom_fake(arg0, arg1);

when custom_fake is defined as a pointer to a custom function, return_val is ignored. in this case, the return value is 1, the last evaluation in the custom function. to make the matter worse, it DOES succeed depending on values.

so, you need to returns zero in the custom_fake.

uint32_t * read8_fake_custom_fake(const uint8_t reg, uint8_t *reg_value)
{
        *reg_value = faked_reg_value;
        return 0;
}

with clear explanation, someone would save hours (or days).