In my last blog I waxed poetic about C. It was heart-felt, but it was also a little bit embarrassing. I do love the language but it does have its share of trouble.
The problem that I run into most often in C is testability, particularly unit-testability. In theory, there should be no problem. It's easy to test simple functions in C. You just call them from a test harness and away you go. The "not so simple functions" are the ones that cause trouble.
In a procedural language, there are at least two types of functions: leaves and branches. Leaves sort of "bottom out"; they don't call anything else other than library functions, and they are relatively easy to test as long as they don't have side effects outside the system. Branches are tougher: they call leaves and other branches. If you test a few branches up from the leaves, you are not really unit testing any more - you're component testing. And, if those leaf functions touch a database or argue across a socket, you're probably system testing through your unit tests, whether you want to be or not.
So, how can we handle this? How can we easily unit test a branch function without going all the way down the call graph?
The nice thing about C is that it presents you with options. You can play clever tricks with the processor and #define various lower level calls, but it's ugly.
Another option that comes up is the link seam. If you have functions that you want to replace you can place them in another library. When you are testing, you can link to a library of stubs. When you are building your production code, you link in the real library. This approach can work, but it leads to a lot of complication. You can only stub functions that you place in a different compilation unit and your makefiles become a mess.
Fortunately, C has a third way of breaking dependencies: function pointers. Let's look at a radically simplified example.
void process_message(struct message *in)
{
struct message out;
encode(in->header, strlen(in->header), out.header);
encode(in->payload, strlen(in->payload), out.payload);
send_message(&out);
}
Can we stub out the send_message function?
How about this? We can introduce a stuct that holds a pointer to the send_message function and an instance of that struct type:
typedef struct {
void (*send_message)(struct message *in);
} message_port_type;
extern message_port_type message_port;
Then, we can change our call to this:
void process_message(struct message *in)
{
struct message out;
encode(out.header, in->header, strlen(in->header));
encode(out.payload, in->payload, strlen(in->payload));
message_port.send_message(&out);
}
All we have to do now is make sure that we initialize the function pointers at startup. If we need to mock those functions, we can set the function pointers to the appropriate mocks prior to each test case.
It looks suspiciously like C++, doesn't it?
I often show this style to C teams, and most of the time, they regard it with suspicion initially. Some (but not all) C programmers regard OO as hype; they think that it muddies the design. But, the testing problem is real, and this technique can help. It's a thin layer of objectness that makes unit testing manageable.

