labs / tiddlers / content / labs / lab02 / _Labs_02_Testing

This lab is getting pretty long, so we will give you the entire test class for Invoice and point out the interesting bits.

If your original InvoiceTest file had a package declaration, then leave that in place, and replace the rest with the following:

import java.time.LocalDate;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static;
import static org.hamcrest.Matchers.not;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class InvoiceTest {

    private Invoice invoice;
    private InvoiceItem item1;
    private InvoiceItem item2;
    private InvoiceItem item3;

    public void setUp() {
        invoice = new Invoice();
        invoice.setCustomerName("Doris Delores");
        invoice.setCustomerAddress("123 Some Street, Some where");

        item1 = new InvoiceItem();
        item1.setProductName("Polkadot Widget");

        item2 = new InvoiceItem();
        item2.setProductName("Dodgy Doohicky");

        item3 = new InvoiceItem();
        item3.setProductName("Fuzzy Widget");


        //intentionally not adding item3 since it is added in testAddItem

    public void tearDown() {

    public void testAddItem() {
        // make sure that item3 does not already exist
        assertThat(invoice.getItems(), not(hasItem(item3)));
        assertThat(invoice.getItems(), hasSize(2));

        // add it

        // check that it was added
        assertThat(invoice.getItems(), hasItem(item3));
        assertThat(invoice.getItems(), hasSize(3));

    public void testRemoveItem() {
        // make sure that item1 does already exist
        assertThat(invoice.getItems(), hasItem(item1));
        assertThat(invoice.getItems(), hasSize(2));

        // delete it

        // make sure that it is gone
        assertThat(invoice.getItems(), not(hasItem(item1)));
        assertThat(invoice.getItems(), hasSize(1));

    public void testGetTotal() {
        assertThat(invoice.getTotal(), is(closeTo(2.02, 0.0001)));


setUp method

We are setting up the domain objects with initial state that we can test against. Basically, we are creating a complete invoice object that has a couple of items in it.

testGetTotal test

There is nothing new here. We are dealing with floating point numbers again, so we use the closeTo method.


We want to be sure that the addItem method is actually adding the item, so we add a pre-condition check to verify that the item we are about to add doesn't already exist, which could cause the test to pass even if the addItem method is incorrect.

We are using the hasItem method to check that the invoice's items collection has the item that was added in the test. If so then the addItem method must have worked correctly.

We are also checking the total size of the items collection with the hasSize method. This is useful to do since it catches bugs relating to left-over testing data that developers have forgotten about, or a bad tearDown method that isn't properly cleaning up the test data.


Again, we have a pre-condition to make sure that the item that is going to be removed actually exists, so that we can be sure that the removeItem method is definitely the reason that the object is not present in the collection.

We are then using the hasItem method to ensure that item1 is no longer in the items collection after the removeItem method was called.

Again, we are using hasSize to catch problems with the test data and to check that the removeItem method didn't remove more items than it should have, which might indicate a missing or incorrect where clause in the SQL delete statement (assuming we are using a database for storage, which we will be in future labs).

Run the tests. All three tests should pass.