1 Problem to Test: A Vending Machine
2 Introduction to JUnit
3 Problems, Part 1
4 JUnit, part 2
5 Problems, part 2
6 What to Turn In

Lab 6: Junit Testing

Kathi Fisler

This lab introduces you to testing with JUnit, a standard testing framework for Java (and one used in upper-level CS courses). This lab will help you learn JUnit and think about testing in the presence of mutation.

1 Problem to Test: A Vending Machine

Start from this simple implementation of a vending machine. The vending machine offers two items: "Candy" and "Gum". The vending machine operations allow someone to deposit money, purchase items, see the current balance in the machine, and restock items. Your job will be to design tests for the vending machine and express them in JUnit.

2 Introduction to JUnit

JUnit is a framework for writing test cases, similar in spirit to Tester, but with some significant differences. Both DrJava and Eclipse have built-in support for creating JUnit test cases (directly under the file menu for DrJava; under the File->New menu for Eclipse). The configuration options (especially under Eclipse) will make more sense if you first write a test suite manually.

If you don’t already have JUnit, download this jar file to your working directory for this lab. Add the jar file to your classpath (as you did for Tester).

To use JUnit, you first need to include the following line:

  import junit.framework.TestCase;

A set of related tests then goes into a class that extends the JUnit TestCase class. If I want to define a class of vending-machine tests, for example, I could create:

  public class VendingTest extends TestCase {

  }

The contents of this class are a series of test methods (similar in spirit to those we have done with Tester). All test methods must start with the letters test:

  public class VendingTest extends TestCase {

  

    public void test1() {

       ...

    }

  }

All that remains is to learn the contents of the test methods. Here are five common test operations you can use (the full list is in the JUnit documentation):

So for example, I could write the following (uninteresting) test suite:

  public class VendingTest extends TestCase {

  

    public void test1() {

       assertTrue(3==3);

    }

  }

Let’s have you write some tests before we cover additional JUnit features.

3 Problems, Part 1

Did you notice that these two tests had some common infrastructure? Namely, both had to start with creating a vending machine and adding some money to the machine. Rather than repeat that code, it would be nice to tell JUnit to always set up that infrastructure before running our tests.

4 JUnit, part 2

Imagine that we had a method to create and initialize our vending machine:

  Vending v;

  

  public void setUp() {

    v = new Vending(5,10);

    v.addMoney(3);

  }

We would like Java to run this method for us before it runs the test cases. This is one of the features of JUnit. JUnit looks for a method with this exact name and type signature; if it exists, JUnit runs it before executing each test case. You can also provide a method called tearDown that JUnit will execute after each test runs (to clean up any lingering modifications to your data made during testing).

Each TestCase class can have its own setUp and takeDown methods. So if you have two sets of tests that need different setup and takedown operations, put them in two separate TestCase classes.

5 Problems, part 2

Consider the following TestCase:

  public class VendTest extends TestCase {

    static Vending v = new Vending(5,5);

  

    public void setUp() {

      v.addMoney(1.5);

    }

  

    public void test2() {

      v.select("Gum");

      assertTrue(v.getBalance()==1);

    }

  

    public void test3() {

      v.select("Candy");

      assertTrue(v.getBalance()==.25);

    }

  }

6 What to Turn In

Turn in your .java files for this assignment.