Time Saving Testing Techniques
October 27, 2004
Dave Hoover : Home
Below are some testing techniques I've picked up lately:


Loop

Motivation

Certain situations require infinite loops. But how does one test infinite loops without adding ugliness to production code?

Solution

Hide the while loop condition behind an interface. Inject a puppet implementation in your tests and a hard coded implementation in production.

Example

class BatteryChecker {
    private final Battery battery;
    private final Loop loop;

    public BatteryChecker(Battery battery, Loop loop) {
        this.battery = battery;
        this.loop = loop;
    }

    public void checkBattery() {
        while (loop.again()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException("Something went wrong.");
            }
            battery.check();
        }
    }
}

interface Loop {
    boolean again();
}

// For production
class InfiniteLoop implements Loop {
    public boolean again() {
        return true;
    }
}

// For testing
class FiniteLoop implements Loop {
    private final int limit;
    private int count;

    public FiniteLoop (int limit) {
        this.limit = limit;
    }

    public boolean again() {
        count++;
        return count < limit;
    }
}

Sleeper

Motivation

Certain situations require sleeping threads. Sleeping threads can slow down test suites. You need the sleeping behavior in your production code, but that sleeping will steal minutes, hours, and days from you over the course of a project when the test suite is run frequently.

Solution

Hide the time-intensive behavior behind an interface. Inject a fast running implementation in your tests and a sleepy implementation in production.

Example

class BatteryChecker {
    private final Battery battery;
    private final Sleeper sleeper;

    public BatteryChecker(Battery battery, Sleeper sleeper) {
        this.battery = battery;
        this.sleeper = sleeper;
    }

    public void checkBattery() {
        while (true) {
            sleeper.sleep();
            battery.check();
        }
    }
}

interface Sleeper {
    void sleep();
}

// For production
class ThreadSleeper implements Sleeper {
    private final long millis;

    public ThreadSleeper (long millis) {
        this.millis = millis;
    }

    public void sleep() {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new RuntimeException("Something went wrong.");
        }
    }
}

// For testing
class SuperFastSleeper implements Sleeper {
    public void sleep() {}
}

Note: Rather than use stubbed out implementations for testing, I would recommend using Mock Objects, specifically jMock.


Home : Dave Hoover Copyright © 2001-2017 Red Squirrel Design, Inc. All Rights Reserved.