Writing tests and demos with stubs, fakes, and monkeypatches - uchicago-cs/chiventure GitHub Wiki
Testing your code with other components in chiventure (including core components) does not require waiting until your code is fully integrated into chiventure (it doesn’t even require waiting until other components are implemented). You can write tests and demos using the following strategies:
- Stubs/Mocks
- Fakes
- Monkeypatching
Stubs/Mocks
Suppose you are writing a component that relies on a function get_player_strength
that is being implemented by another team (Let’s assume a player has an associated “strength” but that this value can change depending on the player’s stats).
We can “stub out” this function in our tests:
int get_player_strength(player_t *plyr)
{
return 42;
}
This is not uncommon in unit tests, even after get_player_strength
is fully implemented, because it allows us to run our tests without dependencies (if the tests called the actual get_player_strength
, they would cross over into being integration tests). Using these stubs will also make the actual integration easier, as they may help us identify potential integration issues early.
A related concept is mocks. While a stub implements an interface in a static manner, a mock will emulate a behaviour in a testable way. For example, suppose I was writing a test for a SAVE
command in the CLI, which should eventually result in a save_game
function being called. Writing the following mock allows me to check that the function was actually called:
int save_game(chiventure_ctx_t *c)
{
/* Assertions checking we have all the information
* we need to save the game */
ctx->unsaved_changes = false;
return SUCCESS;
}
That said, the line between stubs and mocks (and fakes) can be a bit hazy.
Fakes
A “fake” behaves like a full implementation of something, but is not something we would use in production.
In chiventure, we can create full in-memory games that will behave just like a game that was loaded from a WDL file. This is impractical for the final product, but useful for testing, because we can test our code without depending on WDL support.
You can see an example of this in tests/cli/game.c. In particular, the create_sample_ctx
function creates an in-memory game (nothing is being loaded from a WDL file).
IMPORTANT: Generally speaking, fakes should only appear in testing code. Do not create in-memory games anywhere else in the chiventure code.
Monkeypatching
Monkeypatching refers to altering the behavior of a program at runtime.
For example, you can dynamically add new commands to the CLI. This is an easy way of testing new CLI commands before asking the CLI team to add those commands. You can find examples here:
IMPORTANT: Monkeypatching is an acceptable mechanism for building demos before your code is fully integrated with chiventure, but should not make it into the core code of chiventure. If you do write a monkeypatched demo, it should go in the examples/
directory of your component.