ccmockery

Checking if function, tested with CMockery, calls another particular function


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 ?
}

Solution

  • 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