Exercise 3: Unit Testing With JUnit 5

A major topic for COMP5911M is refactoring, and a prerequisite for refactoring is the existence of good unit tests. In this exercise you can review your understanding of unit testing, using the latest version of the JUnit unit testing framework. You can skip this exercise if you already have experience of using JUnit.

Preparation

You should already have a clone of your GitLab repository, created in the first exercise. Download exercise3.zip into the top-level directory of the repository and unzip the archive. This will give you a subdirectory named exercise3, containing files named README.md, build.gradle, etc.

If you haven’t already set up a .gitignore file in your repository, now would be a good time to do so. Adding a .gitignore will ensure that unnecessary files, such as compiler output, don’t get committed to your repository. You can download a suitable .gitignore file from the Learning Resources folder in Minerva.

Remove the Zip archive and then commit the newly added files:

rm exercise3.zip
git add .
git commit -m "Added code for unit testing exercise"

(Note the use of the period character in the git add command above. This ensures that Git will start tracking not only the Exercise 3 files, but also the .gitignore file, if you added it.)

Running Tests

You can do the work for this exercise using a text editor and the command line, or you can use the IntelliJ IDE. See the subsections below for further instructions on how to run tests when following these approaches.

Text Editor & Command Line
  1. In a terminal window, enter this command:

    ./gradlew test
    

    If you are doing this on Windows, use gradlew instead of ./gradlew.

    This will be very slow the first time it runs, because it will need to download the Gradle build system and the JUnit libraries. After a delay, it will compile all the code and then run the tests. It should report that each of them has passed.

  2. Run the command again. Nothing will happen. Gradle avoids running the tests again if there have been no changes to the code since the last time that the tests were run.

IntelliJ IDE
  1. Run IntelliJ and choose Open or Import from the Welcome screen. Select the exercise3 directory and click Open. Wait for the project to be set up. This may be very slow, as IntelliJ may need to download Gradle and the JUnit libraries.

  2. Click on the Gradle button to open the Gradle tool window. This button should be in a vertical toolbar on the right of the IDE window. If you can’t see it, you can select ViewTool WindowsGradle from the main toolbar.

  3. Gradle tasks are organized in a hierarchical folder structure in the Gradle tool window. Open up the Tasks folder and the verification subfolder. Double-click on the test task to run the tests. Test results will appear in a panel at the bottom of the screen.

    Screenshot of unit test results displayed by the IntelliJ IDE

    Unit test results in IntelliJ

  4. When you’ve run a Gradle task, IntelliJ will create a run configuration for it, with a name ending in [test]. This will allow you to rerun tests in the future without needing to open the Gradle tool window. All you need to do is make sure that the relevant configuration is selected in the ‘Run/Debug Configurations’ drop-down menu. You can then run the tests by clicking on the Run button on the toolbar (the one with the ‘green triangle’ icon), or by pressing Ctrl+R.

Test Results Report

When you use Gradle to run the tests, whether that be from the command line or from within IntelliJ, an HTML report on the results will be generated. To view this report, open the file build/reports/tests/test/index.html in a web browser.

Screenshot of the test results report generated by Gradle

Report on test results

Checking the test report is most useful when you have a failing test, as it will show complete details of the failure.

Writing Tests For JUnit 5

  1. You’ve been provided with a class Money, containing code to be tested. You’ll find this class under src/main. The corresponding unit tests are in the class MoneyTest, under src/test. Spend a few minutes examining this code.

  2. In MoneyTest.java, write a new test named centsTooHigh. This should follow the same format as the existing centsTooLow test, but should check that the correct exception is thrown when attempting to create a Money object with greater than 99 cents. Use assertThrows to write the assertion.

    Run the tests again. Make sure that the new test passes before you continue. Stage and commit your changes to the repository.

  3. Write a test named eurosTooLow. This should be similar to centsTooLow, but this time you should write the test so that it also checks the message associated with the exception. Use assertThrows, assertThat and a Hamcrest matcher to do this. See the lecture slides or the Assertions section of the JUnit User Guide for examples of suitable code.

    Run the tests again. Make sure that the new test passes before you continue. Once again, stage and commit your changes (and do this after each of the remaining steps of this exercise).

  4. Write one or more test methods to check that the behaviour of the equals() method in Money is correct.

  5. Write one or more test methods to check that the behaviour of the hashCode() method is correct. (Essentially, hashCode() should return the same value for different Money objects representing the same amount of money, and different values for Money objects that represent different amounts of money.)

  6. Write some test methods to check that the plus() method behaves correctly. Think carefully about the different test cases you will need here!

  7. Stage and commit any remaining code changes, then push your sequence of commits up to gitlab.com with git push.