Search code examples
cunit-testingmockingfacade

Is it possible to exchange a C function implementation at run time?


I have implemented a facade pattern that uses C functions underneath and I would like to test it properly.

I do not really have control over these C functions. They are implemented in a header. Right now I #ifdef to use the real headers in production and my mock headers in tests. Is there a way in C to exchange the C functions at runtime by overwriting the C function address or something? I would like to get rid of the #ifdef in my code.


Solution

  • To expand on Bart's answer, consider the following trivial example.

    #include <stdio.h>
    #include <stdlib.h>
    
    int (*functionPtr)(const char *format, ...);
    
    int myPrintf(const char *fmt, ...)
    {
        char *tmpFmt = strdup(fmt);
        int i;
        for (i=0; i<strlen(tmpFmt); i++)
            tmpFmt[i] = toupper(tmpFmt[i]);
    
    // notice - we only print an upper case version of the format
    // we totally disregard all but the first parameter to the function
        printf(tmpFmt);
    
        free(tmpFmt);
    }
    
    int main()
    {
    
        functionPtr = printf;
        functionPtr("Hello world! - %d\n", 2013);
    
        functionPtr = myPrintf;
        functionPtr("Hello world! - %d\n", 2013);
    
        return 0;
    }
    

    Output

    Hello World! - 2013
    HELLO WORLD! - %D