CMock creates mocks and stubs for C functions. It's useful for interaction-based unit testing, where you want to test how one module interacts with other modules. Instead of trying to compile all those real units together, CMock helps you by creating fake versions of all the "other" modules. You can then use those fake versions to verify that your module is working properly!

CMock uses Ruby scripts to auto-generate C source modules conforming to the interfaces specified in your C header files. It searches your header files for function declarations. For example, you might tell it to look in your NeatStuff.h file, where it sees the following:

ARGS* ParseStuff(char* Cmd);
void HandleNeatFeatures(NEAT_FEATURE_T NeatFeature);

CMock takes those function declarations, and it creates a set of Mock objects and helpers (which are put in a new C and header file called MockNeatStuff.c and MockNeatStuff.h):

intParseStuff(char* Cmd);
void ParseStuff_ExpectAndReturn(char* Cmd, int toReturn);
void ParseStuff_IgnoreAndReturn(int toReturn);
void ParseStuff_StubAndCallback(CMOCK_ParseStuff_CALLBACK Callback);

void HandleNeatFeatures(NEAT_FEATURE_T* NeatFeature);
void HandleNeatFeatures_Expect(NEAT_FEATURE_T* NeatFeature);
void HandleNeatFeatures_ExpectWithArrays(NEAT_FEATURE_T* NeatFeature, int NeatFeature_Depth);
void HandleNeatFeatures_Ignore(void);
void HandleNeatFeatures_StubAndCallback(CMOCK_HandleNeatFeatures_CALLBACK Callback);

Now that you have these new functions, what do you do with them? You can use to help write tests for modules that call functions in NeatStuff.h. For example, this contrived example:

int MyFunc(char* Command)
  int ID;
  ID = ParseStuff(Command);
  case 0: 
    return 1;

  case 1: = 1;
    Neat.cmd = Command;
    return 1;

    return 0;

So, how does that work? How do we write tests using our new Mocked versions? Well, you write a normal-looking Unity test. Before the function under test is called, you can call one or more Expectations. These state what mocked functions you are expecting to be called. You can even specify what arguments you expect to see, AND tell them what data to return. The latter feature is super helpful for injecting data into your functions to verify that they will handle it correctly. It looks something like this:

void test_MyFunc_should_ParseStuffAndCallTheHandlerForNeatFeatures(void)
  int retval;

  //We start by saying what our expectations are, and what we want to return
  NEAT_FEATURES_T ExpectedFeatures = { 1, "NeatStuff" };
  ParseStuff_ExpectAndReturn("NeatStuff", 1);

  //Run Actual Function Under Test
  retval = MyFunc("NeatStuff");

  //We can still verify whatever things we normally would after
  TEST_ASSERT_EQUAL(1, retval);

In this case, our silly little test passes. If we had instead returned 0 as our ID when ParseStuff_ExpectAndReturn was called, we would be able to verify that HandleStupidFeatures is called instead. Whenever CMock comes across a mismatch in what was called versus what was expected, it gives us a helpful Unity failure, like:

MyFunc.c:23:test_MyFunc_should_ParseStuffAndCallHandler2:FAIL:Function 'HandleStupidFeatures' called less times than expected.


MyFunc.c:23:test_MyFunc_should_DoOtherStuff:FAIL:Function 'ParseStuff' Argument 'Cmd' Expected 'NeatStuff' was 'DumbStuff'

The best part is that all of that plumbing was put in with almost no effort on your part. You just had to point CMock at the header files of the modules that your module interacts with! Clearly, this puts a bit more work on your build system, but once it's in place, you're able to do interaction testing quickly and effectively!