Mocking: Stdout/stderr interception
Example: share/doc/aceunit/examples/hello_world_intercepted_obj
How it works
Section titled “How it works”This approach doesn’t mock puts() at all. Only main is renamed with objcopy, same as the other object-based strategies:
objcopy --redefine-sym main=original_main hello.o mocked_hello.oAn Interceptor helper (interceptor.c) redirects both stdout and stderr through pipes: for each stream it dup()s the original file descriptor, opens a pipe, and dup2()s the pipe’s write end over the stream. After original_main() runs, it restores the original file descriptor and reads back whatever was written to the pipe on each stream:
void test_hello(void) { Interceptor *interceptor = Interceptor_start(); int exitStatus = original_main();
char stdoutBuffer[4096]; char stderrBuffer[4096]; Interceptor_stop(&interceptor, stdoutBuffer, sizeof(stdoutBuffer), stderrBuffer, sizeof(stderrBuffer));
assert(0 == exitStatus); assertStrEquals("Hello, world!\n", stdoutBuffer); assertStrEquals("", stderrBuffer);}This verifies the real puts() call end-to-end — both what it wrote and that it wrote nothing to stderr — rather than replacing it with a mock.
When to use this
Section titled “When to use this”Use this when you’d rather assert on real output than introduce a mock/fake for a function as simple as puts. It avoids the extra moving part of a mock implementation, at the cost of testing through an actual pipe/OS interaction rather than an in-process fake.
See also: objcopy override, which mocks puts directly instead of capturing real output.