One of the keys to a well-written unit test is clarity. A great unit test should be short, focused on a single use case, easy to read, and free from noise or complex setup. Here, I will talk briefly about where the critical values should live, inside a test.

Consider the following unit test:

[Test]
public void ArmorFlat_ApplyEffect()
{
AllEffects.Apply(data, performer, new MemberAsTarget(target));

Assert.AreEqual(6, target.State.Armor());
}


While it makes the test generally easy to read with the data built outside of the test, there is one quesion that can’t be answered by reading this test.

Why 6 Armor?

What is special about exactly 6? Would 5 be okay? Why can’t it be 4?

With a bit of effort, we find the answer in the surrounding context.

private EffectData data = new EffectData
{
EffectType = EffectType.ArmorFlat,
FloatAmount = new FloatReference(1)
};

private Member performer = new Member(
1,
"Good Dummy One",
TeamType.Party,
);

private Member target = new Member(
2,
"Good Dummy Two",
"Wooden Dummy",
TeamType.Party,
);


It’s a bit buried in there, but a little bit of reading eventually makes this clear. This test is expecting that if the target already has 5 Armor and there is an effect to change that by +1 Armor, the target should then have 6 Armor.

What can we do to make this test immediately clear?

Let’s refactor the key values back into the test.

[Test]
public void ArmorFlat_ApplyEffect_ArmorIsChangedCorrectly()
{
var target = MemberWithStartingArmor(5);