4. Favorable Unit Test Properties: Encapsulation
● A unit test is just another class
● Do test external behavior
○ Return values
○ Interactions with collaborators
● Do not test internal state
○ Private methods
○ Private variables
○ Reflection
5. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions
6. Favorable Unit Test Properties: Deterministic
● Sources of Non-determinism
○ Math.random
○ java.util.Random
○ System clock methods
○ Multi-threaded code
○ Networks
7. Favorable Unit Test Properties: Deterministic
@Test
public void shouldGenerateColorUntestable(){
ColorGenerator bad = new UntestableRandomColorGenerator();
Color nonDeterministic = bad.generate();
// ...
}
8. Favorable Unit Test Properties: Deterministic
class UntestableRandomColorGenerator implements ColorGenerator {
private final Random _random;
UntestableRandomColorGenerator() {
_random = new Random();
}
public Color generate(){
return Color.color(_random.nextDouble(),
_random.nextDouble(),
_random.nextDouble());
}
}
9. Favorable Unit Test Properties: Deterministic
@Test
public void shouldGenerateColorTestable(){
// Dependency Injection
Random random = new Random(42);
ColorGenerator good = new TestableRandomColorGenerator(random);
Color deterministic = good.generate();
// ...
}
10. Favorable Unit Test Properties: Deterministic
class TestableRandomColorGenerator implements ColorGenerator {
private final Random _random;
TestableRandomColorGenerator() { // prod ctor
this(new Random());
}
TestableRandomColorGenerator(Random random) { // test ctor
_random = random;
}
public Color generate(){
return Color.color(_random.nextDouble(), _random.nextDouble(),
_random.nextDouble());
}
}
11. Favorable Unit Test Properties: Deterministic
class UntestableCalandar implements Calendar {
// ...
public Set<Event> getFutureEvents() {
long nowInMillis = System.currentTimeMillis();
Set<Event> events = new HashSet<Event>();
for (Event event : events){
if(event.getCreationTime() < nowInMillis){
events.add(event);
}
}
return events;
}
}
12. Favorable Unit Test Properties: Deterministic
@Test public void testFutureEvents(){
// Dependency Injection
Time time = new Time() {
public long currentTimeMillis() {
return 42; // between past & present
}
};
TestableCalendar calendar = new TestableCalendar(time);
// ...
}
13. Favorable Unit Test Properties: Deterministic
class TestableCalendar implements Calendar {
private final Time _time;
TestableCalendar(Time time) {
_time = time;
}
public Set<Event> getFutureEvents() {
long nowInMillis = _time.currentTimeMillis();
Set<Event> events = new HashSet<Event>();
// ...
return events;
}
}
14. Favorable Unit Test Properties: Deterministic
interface Time {
long currentTimeMillis();
}
class SystemTime implements Time {
public long currentTimeMillis() {
return System.currentTimeMillis();
}
}
15. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions
17. Favorable Unit Test Properties: Side Effects
● Each unit test is an isolated experiment
● Unit test order should be arbitrary
● Static singletons
● TestNG vs most XUnit test class lifecycle
● Unit Testing and Concurrency agree
18. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions
19. Favorable Unit Test Properties: Simplicity
● KISS … Keep It Simple Stupid
● Test code should not reimplement
production
● A unit test should only test one class
● Test method structure
1 - Build inputs
2 - Create the “system under test”
3 - Perform assertions
20. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions
21. Favorable Unit Test Properties: Fast
● Avoid the Network
○ Retrieving data from a another online system
○ The LixClient interface enabled unit testing
● Go easy on the file system
○ Loading large amounts of test data from disk
● Avoid large computations
○ Generating combinatorial inputs …
○ Time complexity
○ Memory usage
22. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions
23. Unit Test Properties: Assertions
@Test
public void ok(){
Calculator calculator = new Calculator();
Number number = calculator.add(new Integer(3), new Integer(7));
Assert.assertEquals(new Integer(10), number); // three + seven = ten
}
@Test
public void better(){
Calculator calculator = new Calculator();
Number number = calculator.add(new Integer(3), new Integer(7));
Assert.assertEquals(number, new Integer(10), "three + seven = ten");
}
24. Agenda: Favorable Unit Test Properties
● Encapsulation
● Deterministic
● Free of side effects
● Simple
● Fast
● Assertions
● Naming Conventions