Again, here are some experiences about unittesting parts of a game: I'm currently unittesting some sound triggerings. I have a dedicated sound system that is notified via events:
struct SoundEvent {
int object_id;
SoundAction action; // an enum, see below
float pitch, volume; // where 1.0 is "normal"
};
My sounds are grouped to specific actions, specified by an enum:
enum class SoundAction {
Attack, UseItem, CastSpell, Die
};
Additionally, my sound component per object looks like this:
struct SoundData {
map<SoundAction, sf::SoundBuffer const *> sfx;
};
A note about those pointers: They are non-owning raw pointers, because all game resources (including sound buffers) are held by the game session. They are released if the game quits - as the soundsystem is destroyed as well.
Finally: When equipping a weapon, the actor's sound component's "Attack"-action is changed to the weapon's attack sound. This can be unit tested ...
EquipWeaponChangesAttackSound ...
EquipArmorDoesNotChangeAttackSound.
Additionally, triggering the sounds can also be tested: My systems message each other through those events (see above). So when testing the "equip-items"-code, I can fetch all outgoing SoundEvents (without forwarding them to a soundsystem - there is no sound system involved in this test ^^ But there's a SoundSender who produces SoundEvents) and check whether the correct sound (object id + sound action) was triggered.