0

I am learning JUnit and I am testing a simple method, I have a method which populate a list and return it. Although in unit test I provided the same list, the unit test failed.

Code

public List<Transaction> retrieveData() throws ParseException {
        List<Transaction> expResult = new ArrayList();
        Date convertedDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-04-29T13:15:54");
        Transaction tran = new Transaction("A", convertedDate,new BigDecimal("20.00"));
        expResult.add(tran);
        tran = new Transaction("B", convertedDate,new BigDecimal("20.00"));
        expResult.add(tran);
        tran = new Transaction("A", convertedDate,new BigDecimal("20.00"));
        expResult.add(tran);
        tran = new Transaction("B", convertedDate,new BigDecimal("20.00"));
        expResult.add(tran);
        return expResult;

    }

JUnit

@Test
public void testRetrieveData() throws ParseException {
    MyClass instance = new MyClass();
    List<Transaction> expResult = new ArrayList();
    Date convertedDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-04-29T13:15:54");
    Transaction tran = new Transaction("A", convertedDate,new BigDecimal("20.00"));
    expResult.add(tran);
    tran = new Transaction("B", convertedDate,new BigDecimal("20.00"));
    expResult.add(tran);
    tran = new Transaction("A", convertedDate,new BigDecimal("20.00"));
    expResult.add(tran);
    tran = new Transaction("B", convertedDate,new BigDecimal("20.00"));
    expResult.add(tran);

    List<Transaction> result = instance.retrieveData();
    assertEquals(expResult, result);

}

The failed message and stacktrace are as following

Error

expected: java.util.ArrayList<[
   Transaction{cardNumber=A, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=B, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=A, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=B, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}]> 
   but was: java.util.ArrayList<[
   Transaction{cardNumber=A, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=B, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=A, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}, 
   Transaction{cardNumber=B, timestamp=Tue Apr 29 00:00:00 EST 2014, price=20.00}]>
java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:93)
    at org.junit.Assert.failNotEquals(Assert.java:647)
    at org.junit.Assert.assertEquals(Assert.java:128)
    at org.junit.Assert.assertEquals(Assert.java:147)
Jack
  • 6,430
  • 27
  • 80
  • 151
  • 1
    Have you defined `equals()` and `hashCode()` in your `Transaction` class? – Andrew Stubbs Jul 16 '14 at 12:50
  • no should I override the equals class? would you give me an example – Jack Jul 16 '14 at 12:51
  • If you're using eclipse right click on your class, select Source and then "Generate hashCode() and equals()" which will give you a naive implementation. Otherwise I can't give you an example without knowing how you would determine whether two transactions were equal – Andrew Stubbs Jul 16 '14 at 12:57

2 Answers2

1

When comparing the lists, your test is asserting the lists are equals, which will call equals() on all of the elements within the list.

The default implementation of equals for all classes simply asserts that the objects are literally the same (Same pointer).

If you override equals() in your Transaction class to check the values the class holds instead of the references, the test will behave as you expect.

Andrew Stubbs
  • 4,322
  • 3
  • 29
  • 48
0

This is a discussion and thorough answer about a similar issue:

How can I check if two ArrayList differ, I don't care what's changed

Community
  • 1
  • 1
ohwhy
  • 49
  • 7
  • If your link is to an identical question, flag this one as a duplicate. If it's not an answer to this question, post it as a comment, not an answer. – Andrew Stubbs Jul 16 '14 at 13:05