Walkthrough: Unit Tests

Concept: Unit Testing

A unit is a single, clearly stated behavior. In many cases it will be one function, or method.

A unit test is an automated test that verifies that one unit behaves correctly.

We will be writing unit tests using JUnit 4 in IntelliJ. Some example code has been provided for us. We will be writing unit tests for the code that currently exists.

Fork, Clone, and Open Project in IntelliJ

  • Fork this repo
  • Clone your forked version of the repo locally
  • Create a new branch for the new unit tests we will be writing $ git checkout -b my-unit-test-solution
  • Open IntelliJ
  • Choose open folder and navigate to and choose folder car-unit-test-starter

Configure IntelliJ for Java 8

Before we can write any unit tests we need to configure this project for Java 8.

Check out the Configure IntelliJ article for detailed steps.

As a reminder from that configuration article you will need to
  • Set our Project SDK
  • Set our Project language level
  • Set our Project compiler output
  • Mark the main directory as Source Root
  • Mark the test directory as Test Sources Root

Add an Empty Test

We need to create an empty test so that we can create our testing runtime configuration. However, IntelliJ will only find our test class if it has a valid test in the class body.

  • In CarTest.java add an empty test
../../_images/empty-test.png
  • Add JUnit 4 to your class path (click @Test and then option+enter)
../../_images/junit4-classpath.png
  • Import Test, and AssertEquals
../../_images/import-assertequals.png

Create a New Runtime Configuration

Checkout the runtime configuration guide for a step-by-step guide for getting your runtime configuration created

As a reminder from the runtime configuration article you will need to
  • Add a new configuration
  • Name the configuration
  • Select the class file for our tests
  • Apply the configuration
  • Run new configuration by clicking the green arrow
  • View test results
../../_images/first-test-results.png

Currently our one test passes, because emptyTest is our only test, and it’s checking if 10 is 10, which is true.

Write and Run our Unit Tests

  • Write tests
../../_images/completed-tests.png

Our first three tests are very similar to one another. They each have a test_car object, and are checking that the gas tank level is correct after instantiating the car, driving the car within the range, and driving the car exceeding the range.

The assertEquals() method takes three parameters: The value we want to test, What it’s value should be, and the delta (how much the actual, and expected values can differ and still return true).

Our fourth test is a little different. We are going to perform an action to our car object, and we are expecting the object to throw an error. In this case we are going to attempt to add gas to our car that exceeds the gas tank size.

../../_images/test-expected-exception.png

We are able to expect an exception to be thrown by adding (expected = IllegalArgumentException.class) after our @Test annotation. This is our way of telling Junit 4 that this test should pass if an IllegalArgumentException is thrown at any point during this test.

We also are calling the addGas method which has not yet been added to the Car class, we will need to add this functionality to run our test.

The fail() message will be displayed if the test fails. We have to import the fail method into this class to use it.

Let’s add the addGas method to our Car class so we can finish this final test.

  • Add the addGas method to Car.java
../../_images/test-add-gas.png
  • Run your tests
../../_images/failed-car-test.png

My new test failed! In the output I got an unexpected exception. This test was expecting an IllegalArgumentException, but it got an AssertionError execption. This caused my test to fail. Further down in the output log we can see that our fail() statement printed out the statement about not being able to add more gas to the gastank than is possible.

  • Refactor our Car class to throw an exception when too much gas is added to the gas tank
../../_images/test-set-gastank-level.png

We added some code to our setGasTankLevel method that checks if the new gas tank level is greater than the gas tank size, and if it is it throws an IllegalArgumentException.

  • Rerun our tests
../../_images/passed-car-test.png

This time our test passed, and nothing was printed out to the output log! We have successfully written 4 unit tests in this walkthrough!

Hint

You can open a TODO window by going to View then Tool Windows then seelct TODO this opens a box at the bottom of IntelliJ showing you all the TODOs in the project.