Test double that replaces a collaborator that provides indirect input. Stubs can be created “by hand” or by using a mocking framework. Such frameworks often don’t make any distinctions between stubs and mock objects (mocks), which makes people use the terms incorrectly and leads to confusing tests.
A good rule to remember is that a stub can never make a test fail, whereas a mock can. This means that there will never be any assertions or verifications on a stub.
Example
Consider a Robot
class that has some kind of distance sensor.
public class Robot { private Sensor sensor; public Robot(Sensor sensor) { this.sensor = sensor; } public void move() { if (sensor.getDistance() < 10.0) { // do something // ... } } }
In this case, the sensor is a source of indirect input. Because Sensor
is an interface and constructor injection is already in place, stubbing by hand would look like:
public class SensorReturningTooClose implements Sensor { @Override public double getDistance() { return 5.0; } }
And stubbing by a framework would look like this:
Sensor sensor = mock(Sensor.class); when(sensor.getDistance()).thenReturn(5.0);