In this section, let's review what type of unit tests we would want to write and what these tests should assert for some of the methods in the preceding example.
Let's consider what we would assert in writing a unit test that just tested the following logic in the Car.start method. (Remember, we are not interested in testing the dashboard.initialise or engine.start methods yet):
public void start() { dashboard.initialise(); engine.start(); }
For this method, we would assert that the dashboard.initialise and engine.start methods actually get called. So, in a unit test for this method, we are testing the behavior of the start method only. In separate unit tests, we would also test the dashboard.initialise and engine.start methods themselves.
In the case of the engine.start method, shown again in the following code, we want to assert that the dashboard.updateRPMs method was called with the correct idle RPM value and that the state of the engine was correctly set up as running:
public void start() { dashboard.updateRPMs(1000); // Idle speed isRunning = true; }
We are not interested in testing whether the method updated the display; that's the concern of another unit test, which tests the Dashboard.updateRPMs method directly.
Here is the Dashboard.updateRPMs method code again. When writing a unit test for this method, we should validate that any value passed to the rpms parameter was correctly passed to the Display.showMessage method:
public void updateRPMs(Integer rpms) { display.showMessage(10,10, 'RPM:' + rpms); }
In order to write unit tests for these methods and these methods alone, we need the dashboard, display, and engine variables to reference something the compiler will recognize as having the required methods. But this kind of testing also needs to allow us to substitute the real implementation of these methods with special test-only versions so that we can record when the methods are called in order to assert behavior. What we need is mock implementations of the Dashboard, Engine, and Display classes.