Suppose I have a function like this:
public void AddEntry(Entry entry)
{
if (entry.Size < 0)
throw new ArgumentException("Entry size must be greater than zero");
DB.Entries.Add(entry);
}
And a corresponding unit test:
[TestMethod]
[ExpectedException(typeof(ArgumentException), "Entry size must be greater than zero")]
public void AddEntry_TermSizeLessThanZero_ThrowException()
{
Entry e = new Entry(-5);
AddEntry(e);
}
And then I refactor the validation code out:
public void AddEntry(Entry entry)
{
Validate(entry);
DB.Entries.Add(entry);
}
public void Validate(Entry entry)
{
if (entry.Size < 0)
throw new ArgumentException("Entry size must be greater than zero");
}
The unit test no longer describes the validation code.
What’s the best thing to do in this case? Do I just leave Validate() to be tested through AddEntry?
Edit: to clarify, supposing I had a reason to make the refractored code public (a bit contrived in this situation), would I want to duplicate the test code to be thorough?
At this point I wouldn’t add a test to Validate(), since that code is already hit by an existing test. I like that test since it corresponds closely to the class’s requirements.
This changes when you start using Validate() in other functions in the class, or in other classes. Validate() may also be extended to validate different issues, you’ll want to address this.
When Validate() has multiple callers, and Validate() starts testing multiple conditions, you’ll probably want:
It seems adding tests in this manner keeps good coverage while scaling linearly with the number of requirements tested.