Testing
Real I/O is a poor foundation for unit tests. Network operations are slow,
non-deterministic, and do not fail on demand — so error-handling paths go
untested until production breaks them. Capy ships a self-contained toolkit.
It replaces the transport with in-memory mocks, drives coroutines to
completion on the calling thread, and injects failures at every
maybe_fail() site. The toolkit therefore exercises every error branch
automatically. Because each mock satisfies the same concept as its
production counterpart, test code reads the same as production code. The
only difference is the type of the stream you pass in.
What This Section Covers
-
Driving Tests —
run_blockingdrives a coroutine to completion on the calling thread without a real executor.fuseruns the test body repeatedly, injecting an error at eachmaybe_fail()site in turn until every failure path is covered. Thethread_nameheader’sset_current_thread_namefunction labels worker threads so that failures in multi-threaded tests are easier to attribute. -
Mock Streams —
read_stream,write_stream, andstream(a connected pair) implement the partial-I/O concepts from Streams. Use them to test protocol logic that callsread_someandwrite_somewithout touching a socket. -
Buffer Inspection —
bufgrinditerates every split point of a buffer sequence, exercising every chunk-boundary condition;buffer_to_stringconcatenates buffer sequences into astd::stringfor easy assertion.
How the Pieces Fit
A typical test constructs one or more mocks, arms a fuse, and hands the
mocks to the code under test inside a run_blocking call. The fuse
repeats the test body automatically in two full sweeps — error-code mode,
then exception mode. run_blocking keeps the whole thing on the calling
thread. Buffer utilities such as bufgrind and buffer_to_string
wrap the mock data for assertions. They let you verify that every split of
an input buffer produces the same correct output.