2 min read

Can Null Really Simplify Code?

Where and when to use null to simplify your code and add clarity.
Can Null Really Simplify Code?

Test Code

In this article, JUnit will be the testing framework that is used for examples.

Nulls shouldn't be used in production code. Where nulls are really powerful and actually provide code simplicity is in unit tests. Nulls document "this value is irrelevant for what is being tested." Nulls are used in method and constructor parameters that don't apply to what is being tested. Take the following class:

// Java code
public final class Car {

  private final Engine engine;
  private final Transmission transmission;
  private boolean allDoorsLocked = true;

  public Car(final Engine engine, final Transmission transmission) {
    if (engine == null) {
      throw new RuntimeException("Engine is required");
    }

    if (transmission == null) {
      throw new RuntimeException("Transmission is required");
    }

    this.engine = engine;
    this.transmission = transmission;
  }
  
  public boolean isAllDoorsLocked() {
    return allDoorsLocked;
  }
}

Now we want to test that when a car is instantiated, the doors default to locked.

// Java code
@Test
public void defaultsTheDoorsToLocked() {
  final var engine = new Engine();
  final var transmission = new Transmission();
  final var car = new Car(engine, transmission);

  assertThat(car.isAllDoorsLocked(), is(true));
}

Simplifying Test Code Using Null

In the first example, when trying to write a test for it, the null checks make it more difficult to test. You must provide both an Engine and a Transmission, but neither has anything to do with the doors of the car. The idea is to not check for null because you shouldn't be using them in your production code. If the null checks in the production code were removed, you could clean up your unit tests. The following example is with the null checks removed from Car.

// Java code
public final class Car {

  private final Engine engine;
  private final Transmission transmission;

  public Car(final Engine engine, final Transmission transmission) {
    this.engine = engine;
    this.transmission = transmission;
  }
}

Now you can write your unit test as expected, without any pointless objects needed.

// Java code
@Test
public void defaultsDoorsToLocked() {
  final var car = new Car(null, null);

  assertThat(car.isAllDoorsLocked(), is(true));
}

You don't need an Engine or a Transmission to check if the doors are locked. Those dependencies have nothing to do with the car doors. This test is easier to write, easier to read, and gets right to the point.

Conclusion

Nulls shouldn't be used in production code, but in unit tests, they provide a great way to simplify code and add clarity to what is being tested.