This tutorial has been updated for JUnit 5, you can find the old tutorial for JUnit 4 here
One of the key components of writing good software is to ensure that our code is tested. Clearly we can test our applications by running them and checking that we receive the expected response, but in anything but the simplest of apps, some errors can be hard to track - particularly if they do not cause the application to crash. Consider the following code
package uk.ac.chester;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
System.out.println("Please enter a phrase:");
String line = inputScanner.nextLine();
char letter = line.charAt(0);
char upperLetter = convertToUpperCase(letter);
System.out.println(upperLetter);
}
public static char convertToUpperCase(char letter) {
String letterAsString = String.valueOf(letter);
letterAsString = letterAsString.toUpperCase();
char upperLetter = letterAsString.charAt(0);
return upperLetter;
}
}
In order to test the convertToUpperCase()
method we are required to write correct code to use the Scanner, get a string, get a character in a string and then print the output. Even if we wrote code to create the char and modified it to test multiple letters it is still an unwieldy way to test things. Consider if it was part of a large programme, where we couldn't just modify the programmes core functionality to test the one method, it would be very hard to check that the method works correctly.
A solution to this problem is to write code which has the sole purpose of testing a method. The next steps walk you through the process of creating a unit test for the convertToUpperCase method
convertToUpperCase
), selecting 'Navigate' on the menu and choosing 'test'. Then choose the 'create test' option. Alternatively you can right click and choose 'Generate' and 'Test', or press ⇧⌘T (Ctrl + Shift + T on Windows)convertToUpperCase()
methodpackage com.tinyappco;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MainTest
{
@Test
void convertToUpperCase()
{
}
}
The method that is created is designated as a testing method by the @Test
code
You may also notice that the method is inside a new class called MainTest
this convention indicates that methods here will test the corresponding methods in the Main class
package com.tinyappco;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class MainTest {
@Test
public void convertToUpperCase(){
char resultWithA = Main.convertToUpperCase('a');
assertEquals('A', resultWithA);
}
}
The changes made are as follows:
convertToUpperCase()
method in the Main class with the lowercase letter 'a' as the parameter and stores the result as a char public static char convertToUpperCase(char letter) {
// String letterAsString = String.valueOf(letter);
// letterAsString = letterAsString.toUpperCase();
// char upperLetter = letterAsString.charAt(0);
// return upperLetter;
return 'A';
}
char resultWithF = Main.convertToUpperCase('f');
assertEquals('F', resultWithF);
char resultWithUpperC = Main.convertToUpperCase('C');
assertEquals('C', resultWithUpperC);
char resultWith4 = Main.convertToUpperCase('4');
assertEquals('4', resultWith4);
char resultWithUmlautU = Main.convertToUpperCase('ü');
assertEquals('Ü', resultWithUmlautU);
The process of writing tests requires a judgement call to be made my the developer. What are the likely errors to guard against in any given method, and how much time is required to write the tests. At this stage, writing tests may take a long time, for little perceivable gain, however as you become a more proficient programmer, you will become faster at writing tests, and more able to discern which tests should be written.
A further benefit of writing unit tests is that if you make a change to a method (for example you refactor it), it is very quick to re-run the tests to check you haven't broken it!
At the top right hand corner of IntelliJ IDEA is a dropdown list - this shows both the test application and the main application - use the drop down to switch between them so the 'play' button will run the desired application. Ignore the edit and save options for now.
public static String makeTitleCase(String phrase) {
String result = "";
boolean startOfWord = true;
for (int i = 0; i < phrase.length(); i++) {
char letter = phrase.charAt(i);
if (letter == ' ') {
startOfWord = true;
} else {
if (startOfWord) {
letter = convertToUpperCase(letter);
startOfWord = false;
}
}
result += letter;
}
return result;
}
makeTitleCase
method (with that text) and finally print the result to the screen. Verify that typing 'hello world' (without the quotes) results in 'Hello World' being printed.Revisit previous tasks you have completed. Write unit tests to verify the methods in them. Where all the code is in the main method, extract methods as appropriate before writing the unit tests.