I’m writing tests for the following class:
public class Foo : INotifyPropertyChanged
{
private int _failCount;
private int _totalCount;
public double FailRate
{
get
{
double returnValue = 0.0;
if (_totalCount > 0)
{
returnValue = (double) _failCount / _totalCount * 100;
}
return returnValue;
}
}
public int FailCount
{
get { return _failCount; }
set
{
if (value != _failCount)
{
_failCount = value;
onNotifyPropertyChanged();
onNotifyPropertyChanged("FailRate");
}
}
}
public int TotalCount
{
get { return _totalCount; }
set
{
if (value != _totalCount)
{
_totalCount = value;
onNotifyPropertyChanged();
onNotifyPropertyChanged("FailRate");
}
}
}
protected virtual void onNotifyPropertyChanged([CallerMemberName]string name = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
I was writing some tests for the FailRate
property, and it occurred to me that I should probably make sure that getting FailRate
doesn’t throw an exception. The case being someone (probably me) removes the if (_totalCount > 0)
check, and then getting FailRate
throws a DivideBy0Exception
.
So I wrote a test that makes sure getting FailRate
doesn’t throw an exception.
[TestMethod]
public void GettingTheFailRateWhenTheTotalCountIsZeroDoesNotThrowAnException()
{
Defect defect = new Defect();
defect.FailCount = 0;
defect.TotalCount = 0;
double dummy = defect.FailRate;
}
However, that test doesn’t have an explicit check, and will pass as long as the property doesn’t throw an exception.
Is just checking that a property doesn’t throw an exception a “valid” test?
1
In my opinion, yes. All logic – meaning all conditional code – can be tested. And this is an edge case, too.
By the way, this code is not thread-safe – _totalCount
could change between reading its value in if and actually dividing by it. But thread-safety might not be among your requirements.
As for the check being explicit or not, it’s a matter of taste. You could catch DivideByZeroException
and call Assert.Fail
(or whatever it’s called) in the catch
block. More verbose, but very clear for the reader. As a fellow coder, I’d be okay either way.
And that the routine being tested is so simple? Mixing imperial and metric units crashed a space probe worth $125 million, and this doesn’t sound like a very sophisticated bug.
Maybe someone is going to write a similar piece of code for this project – calculating estimated time left, for instance – and having seen this test will prevent a mental lapse by reminding them there are zeroes in this world and zero can’t be divided by? It can’t hurt…
Is just checking that a property doesn’t throw an exception a “valid” test?
Yes, it can be. In this example, I would explicitly check that FailRate
returns 0 for that input.
And I certainly would validate that the bad input is handled properly by writing the test. I’d probably write a test with a negative value as well to make sure it was > 0
rather than == 0
since it takes like 10 seconds and better encodes the requirements into the test.