JUnit Example

junitAfter the post on unit testing I received a request to produce and explain sample code using JUnit. This is what I came up after searching the web using Google. I decided to use Eclipse for this example.

First let’s take a look at the output produced by the main application:

>>> a: 3

>>> b: 4

>>> c: 5

<<< a: 3 b: 4 c: 5

<<< t is: Scalene

An equilateral triangle has all sides the same length. An isosceles triangle has two sides of equal length. A scalene triangle has all its sides of different lengths.scalene

The source for Solution.java follows:

package junit.test.sample;

import java.util.Scanner;

public class Solution {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

System.out.print(“>>> a: “);

int a = sc.nextInt();

System.out.print(“>>> b: “);

int b = sc.nextInt();

System.out.print(“>>> c: “);

int c = sc.nextInt();

System.out.println(“<<< a: ” + a + ” b: ” + b + ” c: ” + c);

Triangle t = new Triangle(a, b, c);

System.out.println(“<<< t is: ” + t.triangleType());

sc.close();

}

}

The program prompts for the 3 sides of a triangle. A triangle is instantiated. The type of triangle is then obtained and printed. The code for the Triangle.java class follows:

package junit.test.sample;

public class Triangle {

// **** ****

enum TriangleTypes {

Equilateral, Isosceles, Scalene

}

// **** attributes ****

int    a;

int    b;

int    c;

// **** constructor ****

public Triangle(int a, int b, int c) {

this.a = a;

this.b = b;

this.c = c;

}

// **** methods ****

public String triangleType() {

String type   = “”;

String errMsg = “”;

// **** check for invalid side sizes ****

if (a <= 0) {

errMsg = “a <= 0”;

}

if (b <= 0) {

errMsg = “b <= 0”;

}

if (c <= 0) {

errMsg = “c <= 0”;

}

// **** check for a side too long ****

if ((a + b <= c) || (b + c <= a) || (c + a <= b)) {

errMsg = String.format(“not a valid triangle a: ” + a + ” b: ” + b + ” c: ” + c);

}

// **** classify the triangle (if needed) ****

if (errMsg.length() != 0) {

type = errMsg;

} else {

if ((a == b) && (b == c)) {

type = TriangleTypes.Equilateral.name();

} else if ((a == b) || (b == c) || (c == a)) {

type = TriangleTypes.Isosceles.name();

} else {

type = TriangleTypes.Scalene.name();

}

}

// **** ****

return type;

}

}

The triangleType() method performs some tests and is they all pass it classifies the specified triangle. Now let’s take a look at the JUnit test output:

<<< setUpClass …

<<< setUp …

<<< testEquilateral …

<<<     type ==>Equilateral<==

<<< expected ==>Equilateral<==

<<< tearDown …

<<< setUp …

<<< testIsosceles …

<<<     type ==>Isosceles<===

<<< expected ==>Scalene<==

<<< tearDown …

<<< setUp …

<<< testScalene …

<<<     type ==>Scalene<==

<<< expected ==>Scalene<==

<<< tearDown …

<<< tearDownClass …

The JUnit code follows from the TriangleTest.java file:

package junit.test.sample;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import junit.test.sample.Triangle.TriangleTypes;

import static org.junit.Assert.*;

public class TriangleTest {

// **** constructor ****

public TriangleTest() {

}

// **** ****

@BeforeClass

public static void setUpClass() {

System.out.println(“<<< setUpClass …”);

}

@AfterClass

public static void tearDownClass() {

System.out.println(“<<< tearDownClass …”);

}

@Before

public void setUp() {

System.out.println(“<<< setUp …”);

}

@After

public void tearDown() {

System.out.println(“<<< tearDown …”);

}

// **** tests ****

@Test

public void testScalene() {

System.out.println(“<<< testScalene …”);

Triangle t = new Triangle(30, 40, 50);

String type   = t.triangleType();

System.out.println(“<<<     type ==>” + type + “<==”);

String expected = TriangleTypes.Scalene.name();

System.out.println(“<<< expected ==>” + expected + “<==”);

assertEquals(type, expected);

}

@Test

public void testEquilateral() {

System.out.println(“<<< testEquilateral …”);

Triangle t = new Triangle(10, 10, 10);

String type = t.triangleType();

System.out.println(“<<<     type ==>” + type + “<==”);

String expected = TriangleTypes.Equilateral.name();

System.out.println(“<<< expected ==>” + expected + “<==”);

assertEquals(type, expected);

}

@Test

public void testIsosceles() {

System.out.println(“<<< testIsosceles …”);

Triangle t = new Triangle(10, 5, 10);

String type = t.triangleType();

System.out.println(“<<<     type ==>” + type + “<===”);

String expected = TriangleTypes.Scalene.name();

System.out.println(“<<< expected ==>” + expected + “<==”);

assertEquals(type, expected);

}

}

java-annotationsOf interest are the import statements. They are satisfied by referencing the junit-4.10.jar file. There are annotations for most of the methods. The following table provides a brief description:

Annotation Description
@Test Turns a public method into a JUnit test case. Adding a timeout will cause the test case to fail after time milliseconds. Adding an expected exception will cause the test case to fail if exception is not thrown.
@Before Method to run before every test case.
@After Method to run after every test case.
@BeforeClass Method to run once, before any test cases has run.
@AfterClass Method to run once, after all test cases has run.

Even though the sample code does not show @Test(timeout = 1234) I included it in the description of the @Test annotation because it is useful and always used by HackerRank :o)junit_methods

The following table contains a list of useful assertions:

Method Description
assertTrue(test) Fails if the Boolean test is false.
assertFalse(test) Fails if the Boolean test is true.
assertEquals(expected, actual) Fails if the values are not equal.
assertSame(expected, actual) Fails if the values are not the same (by ==).
assertNotSame(expected, actual) fails if the values are the same (by ==).
assertNull(value) fails if the given value is not null.
assertNotNull(value) Fails if the given value is null.
fail() Causes current test to immediately fail.

It is extremely important to design classes and methods so they can be tested. Always include unit testing when developing code. If possible use some tool to automatically and continuously run tests on your code.

If you have comments or questions feel free to send me a message.

John

john.canessa@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *