I'm trying to practice TDD, by using it to develop a simple like Bit Vector. I happen to be using Swift, but this is a language-agnostic question.
My BitVector
is a struct
that stores a single UInt64
, and presents an API over it that lets you treat it like a collection. The details don't matter much, but it's pretty simple. The high 57 bits are storage bits, and the lower 6 bits are "count" bits, which tells you how many of the storage bits actually store a contained value.
So far, I have a handful of very simple capabilities:
- An initializer that constructs empty bit vectors
- A
count
property of typeInt
- An
isEmpty
property of typeBool
- An equality operator (
==
). NB: this is a value-equality operator akin toObject.equals()
in Java, not a reference equality operator like==
in Java.
I'm running into a bunch of cyclical dependancies:
The unit test that tests my initializer need to verify that the newly constructed
BitVector
. It can do so in one of 3 ways:- Check
bv.count == 0
- Check
bv.isEmpty == true
- Check that
bv == knownEmptyBitVector
Method 1 relies on
count
, method 2 relies onisEmpty
(which itself relies oncount
, so there's no point using it), method 3 relies on==
. In any case, I can't test my initializer in isolation.- Check
The test for
count
needs to operate on something, which inevitably tests my initializer(s)The implementation of
isEmpty
relies oncount
The implementation of
==
relies oncount
.
I was able to partly solve this problem by introducing a private API that constructs a BitVector
from an existing bit pattern (as a UInt64
). This allowed me to initialize values without testing any other initializers, so that I could "boot strap" my way up.
For my unit tests to truly be unit tests, I find myself doing a bunch of hacks, which complicate my prod and test code substantially.
How exactly do you get around these sorts of issues?
BitVector
is a perfectly fine unit size for unit testing and immediately resolves your issues that public members ofBitVector
need each other to make meaningful tests.