Previous Lecture Lecture 5 Next Lecture

Lecture 5, Mon 04/15

Exceptions, JUnit Testing

Exception handling

Exception Object

Try / Catch

Example

public class SomeClass {
    private Scanner s;
    public SomeClass() {
        s = new Scanner(System.in);
    }

    public int getInt() {
        int value = 0;
        System.out.print("Enter a positive number: ");
        try {
            value = Integer.parseInt(s.nextLine());
        } catch (Exception e) {
            // What exceptions can happen based on the user?
            System.out.println("Caught Exception: " + e);
        }
        s.close();
        return value;
    } 
}
public static void main(String args[]) {
    SomeClass x = new SomeClass();
    System.out.println("x = " + x.getInt());
}
User Enters Valid Integer: 10
x = 10

User Enters Invalid Integer: abcd
Caught Exception: java.lang.NumberFormatException: For input string: "abcd"
x = 0

User Enters an Integer not in range: 9999999999
Caught Exception: java.lang.NumberFormatException: For input string: "9999999999"
x = 0

Catching any Exception in Main

Handling Multiple Exceptions

Example

// In SomeClass.java
private int[] array;

public SomeClass() {
    // Comment this out see a NullPointerException
    array = new int[100];
}

// ...

public void updateArray(int pos, int value) {
    try {
        array[pos] = value;
    } catch (IndexOutOfBoundsException e) {
        System.out.println("In IndexOutOfBoundsException");
            System.out.println(e);
    } catch (NullPointerException e) {
        System.out.println("In NullPointerException");
        System.out.println(e);
    }
}
// Lecture.java
public static void main(String args[]) {
    SomeClass x = new SomeClass();
    x.updateArray(100, 100);
}

Some Cases:

Finally Block

Example

// Change updateArray in SomeClass.java to take in user input
public void updateArray() {
        int pos = 0;
        int value = 0;
        try {
            System.out.print("Enter position: ");
            pos = Integer.parseInt(s.nextLine());
            System.out.print("Enter value: ");
            value = Integer.parseInt(s.nextLine());
            array[pos] = value;
            System.out.println("Updated array[" + pos + "] = " + value);
        } catch (NumberFormatException e) {
            System.out.println("In NumberFormatException block");
            return;
        } catch (IndexOutOfBoundsException e) {
            System.out.println("In IndexOutOfBoundsException block");
            return;
        } catch (NullPointerException e) {
            System.out.println("In NullPointerException block");
            return;
        } catch (Exception e) {
            System.out.println("In Exception block");
            return;
        } finally {
            System.out.println("In finally block");
            s.close();
        }
        System.out.println("exiting method");
    }
// in main
x.updateArray();

Combining Exceptions into one block

public static void main(String args[]) {
    SomeClass x = new SomeClass();

    try {
        x.updateArray();
    } catch (IndexOutOfBoundsException | NullPointerException e) {
        System.out.println("In multiple exception catch block");
    }
}

Creating Your Own Custom Exception

// MyException.java
// Create an Exception called MyException extending the Exception class
public class MyException extends Exception {}
// Catch or throw your exception whenever you want.
// Example of throwing the Exception to the caller.
public void someMethod(int x) throws MyException {
    if (x == 0) {
        throw new MyException();
    }
}

Testing

Test Suite

Example of building our own test function

public static int getBiggestInt(int a, int b, int c, int d) {
    if (a >= b && a >= c && a >= d) {
        return a;
    } else if (b >= a && b >= c && b >= d) {
        return b;
    } else if (c >= a && c >= b && c >= d) {
        return c;
    } else {
        return d;
    }
}

public static void runTestCase(int a, int b, int c, int d, int expected) {
    int result = getBiggestInt(a, b, c, d);
    if (result != expected) {
    System.out.println("result: " + result + " != expected: " + expected);
    } else {
        System.out.println("result: " + result + " == expected: " + expected);
    }
}

public static void main(String args[]) {
    // normal test cases
    runTestCase(1,2,3,4,4);
    runTestCase(1,2,4,3,4);
    runTestCase(1,1,3,2,3);
    runTestCase(-1,-2,-3,-1,-1);
        
    // Boundary Cases
    runTestCase(Integer.MAX_VALUE, 3,4,5,Integer.MAX_VALUE);
    runTestCase(3,Integer.MAX_VALUE,4,5,Integer.MAX_VALUE);
    runTestCase(Integer.MIN_VALUE,Integer.MIN_VALUE, -1, 0, 0);
    //...
}

Some Types of Test Cases

JUnit

Some JUnit Methods

assertEquals(expected_value, result_of_test);
assertFalse(boolean_result);
assertTrue(boolean_result);
assertNull(some_object);
assertArrayEquals(array, expected_array);
.. And many more!

https://junit.org/junit4/javadoc/latest/

Using JUnit Example

// Example.java
public class Example {

    public int getBiggestInt(int a, int b, int c, int d) {
        if (a >= b && a >= c && a >= d) {
            return a;
        } else if (b >= a && b >= c && b >= d) {
            return b;
        } else if (c >= a && c >= b && c >= d) {
            return c;
        } else {
            return d;
        }
    }
}
// Tester.java
import org.junit.Test;
import org.junit.Before;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import static org.junit.Assert.assertEquals;

public class Tester {

    private int[] array;
    private Example b; // contains getBiggestInt method defined above

    @Before // Executed before each test in this class
    public void executeBeforeEachTest() {
        System.out.println("@Before: see before every test");
        array = new int[10];
        b = new Example();
    }

    @Test
    public void testInsertItem() {
        array[0] = 0;
        array[1] = 1;
        array[2] = 2;
        array[3] = 3;
        
        assertEquals(array[0], 0);
        assertEquals(array[1], 1);
        assertEquals(array[2], 2);
        assertEquals(array[3], 3);
    }

    @Test
    public void getBiggestTest() {
        assertEquals(b.getBiggestInt(1,2,3,4), 4);
        assertEquals(b.getBiggestInt(1,2,4,3), 4);
    }

    @Test
    public void getBiggestBoundaryTest() {
        assertEquals(b.getBiggestInt(Integer.MAX_VALUE, 3,4,5), Integer.MAX_VALUE);

        assertEquals(b.getBiggestInt(3, Integer.MAX_VALUE,4,5), Integer.MAX_VALUE);
    }

    // Testing an Expected Exception was thrown
    @Test(expected=ArithmeticException.class)
    public void testExceptionThrown() {
        int x = 0;
        int y = 1;
        int z = y / x;
        // Should crash, but doesn't since we're telling the test
    // that an exception should happen.
    }

    @After
    public void executeAfterTest() {
        System.out.println("@After: See this after every test");
    }

    @AfterClass
    public static void executeAfterAllTests() {
        System.out.println("@AfterClass: See this once after all tests");
    }

    @BeforeClass
    public static void executeBeforeAllTests() {
        System.out.println("@BeforeClass: See this once before all tests");
    }
}

Executing JUnit from command line

  1. Get the JUnit4 jar from http://cs.ucsb.edu/~richert/cs56/lib/junit-4.8.2.jar
  2. Put it in your directory or a sub folder where your java files are (lib folder for example).
  3. Compile all .java files and set the classpath to the current directory and where the junit jar exists.

javac -cp .:lib/* Tester.java Example.java

java -cp .:lib/* org.junit.runner.JUnitCore Tester

Using an IDE (such as Eclipse)