-3

I am facing problem in writing mock code using CMockery for a function shown below. Can you please give me some hint? I want to test if startCalCompute is called and also to assign value to updateMode, so that it is not equal to SYSTEM_CAL_CONFIG. All I need is a starting point or hint.

foo.c

static void checkSystem(void)
{
#ifndef CAL
    startCalCompute();
#endif

    if( SYSTEM_CAL_CONFIG != updateMode )
    {
        updateLogevent(); 
    }

    ...
}

testfoo.c

void Test_checkSystem( void ** state )
{   
    // what to do here to check if startCalCompute() is called ?
}
samprat
  • 2,150
  • 8
  • 39
  • 73
  • What if? What else? What is `will_return`? – Paul Ogilvie Jul 21 '17 at 14:41
  • I'm not sure CMockery can help you here; it looks like you're testing the `checkSystem()` function directly, not mocking its dependencies. Are there any effects (including side-effects) of the function that you can detect independently? – Mark Benningfield Jul 26 '17 at 22:23

1 Answers1

2

I want to assign value to updateMode so that it is not equal to SYSTEM_CAL_CONFIG

If updateMode depends on value, which you get from another function and you want to control it during the test, then you should create a test double of that function. Here is a good answer explaining mocks in particular. If it is calculated entirely inside checkSystem, then test driver should not modify it, as its purpose is only to check the overall result.

checkSystem.c

/* checkSystem depends on a value returned by this function */
int getUpdateMode (void);

/* This function knows nothing about testing. It just does
   whatever it was created to do. */
void checkSystem (void)
{
    int updateMode = getUpdateMode ();
    if (SYSTEM_CAL_CONFIG != updateMode)
    {
        ...
    }
}

test_checkSystem.c

/* When testing checkSystem, this function
   will be called instead of getUpdateMode */
int mock_getUpdateMode (void);
{
    /* Get a value from test driver */
    int updateMode = (int) mock();

    /* Return it to the tested function */
    return updateMode;
}

void test_checkSystem_caseUpdateMode_42 (void ** state)
{
    int updateMode = 42;       /* Pass a value to mock_getUpdateMode */
    will_return (mock_getUpdateMode, updateMode);

    checkSystem ();            /* Call the tested function */
    assert_int_equal (...);    /* Compare received result to expected */
}

I want to test if startCalCompute is called

If startCalCompute() is conditionally compiled to be called by checkSystem(), then you could conditionally compile whatever you want to be done in tests:

void startCalCompute (void);
void checkSystem(void)
{
#ifdef CAL
    startCalCompute();
#endif
}

void test_checkSystem (void ** state)
{
#ifdef CAL
    ...
#endif
}

If you need to make sure that particular function was called and that depends on a runtime condition, or if some functions were called in a specific order, there are no tools in CMockery to do that. However, there are in CMocka, which is a fork of CMockery and is quite similar. Here is how you would do that in CMocka:

checkSystem.c

void startCalCompute (void);
void checkSystem (void)
{
    if (...)
        startCalCompute ();
}

test_checkSystem.c

/* When testing checkSystem, this function
   will be called instead of startCalCompute */
void __wrap_startCalCompute (void)
{
    /* Register the function call */
    function_called ();
}

void test_checkSystem (void ** status)
{
    expect_function_call (__wrap_startCalCompute);
    checkSystem ();
}

Now if checkSystem will not call startCalCompute, the test will fail like this:

[==========] Running 1 test(s).
[ RUN      ] test_checkSystem
[  ERROR   ] --- __wrap_startCalCompute function was expected to be called but was not.
test_checkSystem.c:1: note: remaining item was declared here

[  FAILED  ] test_checkSystem
[==========] 1 test(s) run.
[  PASSED  ] 0 test(s).
[  FAILED  ] 1 test(s), listed below:
[  FAILED  ] test_checkSystem
  • thanks mate thats quite helpful. just one doubt assert_int_equal (...); /* Compare received result to expected */ what I need to compare here . One value is updateMode which I received from mock function.What will be other value? Since checkSystem return void how would i compare updateMode from inside that function? – samprat Jul 27 '17 at 12:01
  • @samprat Well, if you the only thing you want to check is that your function calls another function, then you don't need this assertion. But generally, if you test a function, you want to make sure it produces the right result, not just calls another one. If `checkSystem` would return or change variable, that is where you would check if it did it right. –  Jul 27 '17 at 13:43
  • @samprat I would recommend checking out the `cmocka` manuals instead of those you get for `cmockery` from Google. They are much clearer and easier to understand, and most of the stuff you can do in `cmockery` in the exact same way, since these two frameworks share the same code base. And after all, maybe you don't even need a unit testing framework for your purpose. –  Jul 27 '17 at 14:11
  • Thanks a lot Sergey B for help. – samprat Jul 31 '17 at 14:54