This document discusses good and bad properties of unit tests. It provides examples of good unit tests that are understandable, maintainable, repeatable, necessary, granular, and fast. Bad unit tests may not be understandable, maintainable, repeatable, necessary, granular, or fast. The document also discusses how to design code for testability by injecting dependencies like clocks to control test conditions. Unit tests should be treated as an executable specification and avoiding writing legacy code without tests.
5. @Test
public void scale() {
Date now = new Date();
Calendar calBegin = Calendar.getInstance();
calBegin.setTime(now);
calBegin.add(Calendar.HOUR, -4);
Date begin = calBegin.getTime();
Period p = new Period(4);
long delta = p.getBegin().getTime() -
begin.getTime();
Assert.assertTrue(
p.getEnd().compareTo(now) >= 0);
logger.trace(delta);
Assert.assertTrue(delta < 10 && delta > -10);
Assert.assertEquals(
new Integer(4), new Integer(p.getScale()));
}
6. [Test]
public void asterisk_should_format_to_em()
{
// Context
Formatter f = new MarkdownFormatter();
String expected = "This is <em>em</em> text";
// Action
String actual = f.Format("This is *em* text");
// Outcome
Assert.AreEqual(expected, actual);
}
10. public interface CustomerBuilder {
public CustomerBuilder standardSingleMale();
public CustomerBuilder standardSingleFemale();
public CustomerBuilder smoker();
public CustomerBuilder hasOccupation(String occupation);
public Customer build();
}
16. [Test]
#region TestCase...
public void TestMapFromRomanNormalToRomanOnes(
string roman, int times)
{
var actual = _engine.ToRomanOnes(roman);
var expected = _engine.Repeat('I', times);
Assert.That(actual, Is.EqualTo(expected));
}
20. Properties of unit testing
Understandable
Maintainable
Repeatable
Necessary
Granular
Fast
21. Look back at your index card
For each of your ‘good’ things, which of
the properties does it exhibit?
For each of your ‘bad’ things, which of
the properties does it contravene?
23. None of this is a substitute
for writing testable code.
24. class PriceCalculator {
public Price getPrice() {
if (DateTime.Compare(DateTime.Now,PRICE_RISE_DATE)<0){
return LOW_PRICE;
} else {
return HIGH_PRICE;
}
}
}
25. [Test]
public void prices_should_increase_on_2013_03_31()
{
PriceCalculator calc = new PriceCalculator();
// How can we set the date?
// ...
}
26. class PriceCalculator {
public PriceCalculator( SystemClock clock ) {
clock_ = clock;
}
public Price getPrice() {
if (DateTime.Compare(clock.Now, PRICE_RISE_DATE)<0){
return LOW_PRICE;
} else {
return HIGH_PRICE;
}
}
}
27. [Test]
public void prices_should_increase_on_2013_03_31()
{
SystemClock clock = new SystemClock(2013, 03, 31);
PriceCalculator calc = new PriceCalculator(clock);
// Now we control the date?
// ....
}