Testing with JUnit in JGrasp

JUnit is the most widely used unit testing framework for Java. It helps to automate the process of running tests and reporting results. The goal of today's lab is to get comfortable writing tests in JUnit and interpreting the results.

Getting Ready

Before going any further you should:
  1. Make a directory for this lab.
  2. Download the following files into your lab directory:
  3. Configure JGrasp to use JUnit:
    • Select JUnit->Configure under the JGrasp Tools menu.
    • In the box labeled "JUnit Home" browse to the directory where you saved the JUnit .jar file, and click OK.
    • If all went well a green and red box should now appear in your JGrasp toolbar:

1. Creating A JUnit Test Class

  1. Open Account.java in a JGrasp editor window.
  2. Take a few minutes to familiarize yourself with the Account class.
  3. Now click on the "Create JUnit test file" Button: . This should automatically generate a Java file named AccountTest.java. You should also see three new buttons in the JGrasp task bar for compiling, running and debugging JUnit test classes: , , .
  4. Take a minute to look over AccountTest.java. What do you think will happen when this class is executed?
  5. Compile and run AccountTest.java using the new JUnit-specific buttons. What happened?
  6. Now remove @Test from before the defaultTest method, and run AccountTest.java again. What happened?
  7. MORE INFORMATION: In Java, identifiers prefixed by the at-sign are referred to as "annotations". Annotations are not complied as Java instructions. Instead, their purpose is to provide additional information about annotated code. This information may then be read by the Java compiler or by other software tools. The JUnit package uses the @Test annotation to mark methods that should be executed as JUnit tests. (You can find more information about annotations in the Java Tutorials.)

2. Setting Up a Test Fixture

  1. Look at the setUp method that was automatically generated by JGrasp. The @Before annotation tells JUnit that this method must be executed before each test is run. Typically, a setup method is used to initialize instance variables that are useful across multiple tests.
  2. In writing testing methods for the Account class, it will be useful to have access to a pre-initialized account object. Add a private instance variable named testAccount to the AccountTest class, and add code to the setUp method to create a new account object and assign it to testAccount.

3. Testing isEligibleForCharge

  1. Ultimately, each of the non-trivial methods of the Account class will need to be tested. We will start small in today's lab by coding some tests for the isEligibleForCharge method. Take a minute to carefully read the JavaDocs for that method to ensure that you understand its expected behavior then consider the following situations and determine the correct output of isEligibleForCharge for each one.
    • A newly created account.
    • An open account with $500.01 in purchases.
    • An open account with $500.00 in purchases.
    • An open account with $499.99 in purchases.
    • A closed account with total purchases above $500.00.
    • A closed account with total purchases below $500.00.
    • An account that once had a purchase total above $500.00, but now has a purchase total below $500.00 as a result of returns.
  2. Write JUnit test methods covering each of the situations described above. Choose descriptive method names for each test. Here is a possible implementation of the first one to get you started:
         /***********************************************************
         * Test that newly created accounts are not eligible for charge
         * accounts.
         ***********************************************************/
        @Test public void newlyOpenedNotEligible() 
        {
            Assert.assertFalse("New accounts should not be eligible for charges.",
                    testAccount.isEligibleForCharge());
        }
    
    The method Assert.assertFalse takes two arguments: The first (optional) argument is an error message that will be displayed if the test fails. The second argument is a boolean value that must be false for the test to pass. The Assert class has several other assertXXX methods for testing different expected outcomes. These include assertTrue, assertEquals, assertNull and others. You should choose the appropriate assert method for the test that you are writing.
  3. Execute your tests. If all went well, you should see JUnit output like the following, indicating that the Account class has passed all tests.
    JUnit version 4.10
    .......
    Time: 0.007
    
    OK (7 tests)
    
    

4. Testing an Alternate Implementation of Account

  1. Imagine that a coworker has proposed an alternate implementation of the Account class. Before replacing our current implementation, we want to make sure that the proposed alternative passes all of the existing tests. Download the file Account.class to your lab directory, overwriting your existing Account.class file. (Be careful not to re-compile Account.java until you are finished with this exercise. Doing so will overwrite the Account.class file that you are testing.)
  2. Re-execute the JUnit tests that you wrote above. What happens?
  3. Without being able to look at the source, what errors do you think were made by the programmer of this version of the Account.java class?