I am writing a test class for my GiftSelector class using JUnit in BlueJ. When I run the testGetCountForAllPresents() method, I get a NullPointerException in the line:
assertEquals(true, santasSelector.getCountsForAllPresents().get(banana) == 3);
The strange thing about this NPE is that it rarely appears when I run a test once, but often appears a second time when I run a test. Sometimes this does not appear until I checked the test 7-8 times in a row.
The error message I get is an exception message.
NPE on line 215 in GiftSelectortest.testGetCountForAllPresents
Code for my test class:
import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * The test class GiftSelectorTest. The GiftSelector that you are * testing must have testMode enabled for this class to function. * This is done in the setUp() method. */ public class GiftSelectorTest { private GiftList giftList1; private GiftList giftList2; private GiftList giftList3; private Child jack; private Child bob; private Child dave; private Child naughty1; private GiftSelector santasSelector; private Present banana1; private Present orange; private Present banana; private Present apple; private Present bike; private Present doll; private Present got; private Present pearlHarbour; private Present dog; private Present cat; private Present ball; private Present heineken; /** * Default constructor for test class GiftSelectorTest */ public GiftSelectorTest() { //Nothing to do here... } /** * Sets up the test fixture. * * Called before every test case method. */ @Before public void setUp() { santasSelector = new GiftSelector(); santasSelector.setTestMode(true); jack = new Child("Jack", 20, "1 A Place", true, true, true, false); bob = new Child("Bob", 10, "2 A Place", true, true, true, true); dave = new Child("Dave", 10, "3 A Place", true, true, true, true); naughty1 = new Child("John", 5, "4 A Place", true, true, true, true); giftList1 = new GiftList(jack); giftList2 = new GiftList(bob); giftList3 = new GiftList(dave); banana = new Present("banana", "fruit", 10); orange = new Present("orange", "fruit", 10); banana1 = new Present("banana", "fruit", 10); apple = new Present("apple", "fruit", 10); bike = new Present("bike", "toy", 200); doll = new Present("doll", "toy", 40); got = new Present("game of thrones", "dvd", 50); pearlHarbour = new Present("pearl harbour", "dvd", 20); dog = new Present("dog", "animal", 100); cat = new Present("cat", "animal", 80); ball = new Present("ball", "toy", 5); heineken = new Present("heineken", "beer", 1.60); } /** * Tears down the test fixture. * * Called after every test case method. */ @After public void tearDown() { //Nothing to do here... } @Test public void testGetCountForAllPresents() { System.out.println(santasSelector.getCountsForAllPresents()); //Test on empty GiftSelector assertNull(santasSelector.getCountsForAllPresents()); //Test on a GiftSelector with one giftlist containing one present giftList1.addPresent(banana); santasSelector.addGiftList(giftList1); System.out.println(santasSelector.getCountsForAllPresents()); assertEquals(true, santasSelector.getCountsForAllPresents().get(banana) == 1); //Test when GiftSelector contains 2 giftlists, each containing the same present object giftList2.addPresent(banana); santasSelector.addGiftList(giftList2); System.out.println(santasSelector.getCountsForAllPresents()); assertEquals(true, santasSelector.getCountsForAllPresents().get(banana) == 2); //Test when GiftSelector contains 3 giftlists, 2 containing the same present object and another containing an identical present but with a different present instance giftList3.addPresent(banana1); santasSelector.addGiftList(giftList3); System.out.println(santasSelector.getCountsForAllPresents()); assertEquals(true, santasSelector.getCountsForAllPresents().get(banana) == 3); //This is the line I get the NPE //Test when GiftSelector contains 3 giftLists, the first with one with a banana, the second with a banana and apple, and the third with a banana1 and ball giftList2.addPresent(apple); giftList3.addPresent(ball); System.out.println(santasSelector.getCountsForAllPresents()); assertEquals(true, santasSelector.getCountsForAllPresents().get(banana) == 3); assertEquals(true, santasSelector.getCountsForAllPresents().get(apple) == 1); assertEquals(true, santasSelector.getCountsForAllPresents().get(ball) == 1); } @Test public void testGetMostPopularPresent() { //Test on empty GiftSelector assertNull(santasSelector.getMostPopularPresent()); //Test on a GiftSelector with one giftList and one Present giftList1.addPresent(heineken); santasSelector.addGiftList(giftList1); assertEquals(true, santasSelector.getMostPopularPresent().comparePresent(heineken)); //Tset on a GiftSelector with 1 giftList and 2 presents, one more expensive than the other giftList1.addPresent(banana); assertEquals(true, santasSelector.getMostPopularPresent().comparePresent(banana)); //Test on a GiftSelector with 1 giftList and 3 presents. Banana and Apple are equal in price, and are both in the top3, //therefore it should return the present closest to the start of the list giftList1.addPresent(apple); assertEquals(true, santasSelector.getMostPopularPresent().comparePresent(banana) || santasSelector.getMostPopularPresent().comparePresent(apple)); //Test on a GiftSelector with 2 giftLists, the second list containing banana1, an indentical present to banana giftList2.addPresent(banana1); santasSelector.addGiftList(giftList2); assertEquals(true, santasSelector.getMostPopularPresent().comparePresent(banana)); //Test on a GiftSelector with 2 giftLists, the first containing four presents and the second containing 2 presents. //This tests to see if top3 is working. giftList1.addPresent(bike); giftList2.addPresent(bike); assertEquals(true, santasSelector.getMostPopularPresent().comparePresent(bike)); } }
I have included only those testing methods that reference the getCountsForAllPresents() method. You will notice that I added print statements before each call to the assertEquals() method, containing the getCountForAllPresents() method. Interestingly, in front of the line where I get the NPE, the print statement prints the correct value for the HashMap returned by getCountForAllPresents() .
The only other strange thing I noticed is that when I look at the testGetCountForAllPresents() method using BlueJ's built-in debugger, I notice that giftList3 does not display in santaMap HashMap in santasSelector , but the print statement still prints the correct count , implying that he should know about giftList3 .
Code for getCountForAllPresents() :
public HashMap<Present, Integer> getCountsForAllPresents() { if(!santaMap.isEmpty()) {
I have to explain that santaMap is a HashMap , with a Child object as a key and a GiftList object as a value. It basically displays the baby on his Christmas wish list. A santaMap can contain only one wish list with the same child.
I donβt know why I get NPE, is it somehow related to the way I wrote the getCountForAllPresents() method? How did I apply the test method / class?