ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
652 stars 269 forks source link

How to mock local variable #461

Closed tdd2454 closed 3 months ago

tdd2454 commented 9 months ago

Suppose I have a function like below:

`void test_function(int32_t iteration) { int32_t index; int32_t x = 0;

for (index = 0; index <= iteration; index++)
{
    if(x == 0){
        function_1();
        x = x+1;
    }
    else if(x == 1){
        function_2();
        x = x+2;
    }
    else{
        function_3();
        x = 0;
    }
}

}`

How can we mock the conditions of if statement (x) so that we check different branches. Do we need to check values of x at the end? And the for loop, suppose like it loops 10 times, do I need to calculate which functions it will execute and mock them. Like:

function_1_Expect() function_2_Expect() function_3_Expect() ....... running for 10 times

math3os commented 7 months ago

in your test:

extern int x

test_testloop() {
  x=0;
  testloop();

in your code you can use a #define who will put x with static or not depending if you running tests or no

mvandervoord commented 7 months ago

Because you're testing a loop that is running a predefined number of times, I think the original method you describe is your best bet. x is always starting at zero (it's not a static), so it should be the same sequence of values each time.

You are correct that you'd need to set up the expectations for each iteration you'd want something to get called in. If it were me, I'd use comments to make it more clear what it happening... something like this:

(also, test_function is a bad example name to use as it starts with test_ but it's not the test, it's the thing being tested. hahahah!)

void test_test_function_should_handle_four_iterations(void)
{
    // 0th iteration
   function_1_Expect();

    // 1st iteration
    function_2_Expect();

    // 2nd iteration
    function_3_Expect();

    // 3rd iteration
    function_1_Expect();

    test_function(4);
}

Make sense?

If x had been a static variable, where you needed to control it for each test, I would have done this instead:

#ifdef TEST
int32_t x = 0;
#endif

void test_function(int 32_t iteration)
{
    #ifndef TEST
    static int32_t x = 0;
    #endif 

    // same as before
}

You could then extern x into your test and control it for each test.