0

I have an interface test class that implements another super-class. In the test class I have a method that is supposed to retrieve all objects in the ArrayList. First it checks to see if it is empty. If not, it should return the whole list. Here is what I have attempted.

public class ProductDBImpl implements ProductDB {

// field declarations
ArrayList<Product> products = new ArrayList<Product>();
@Override
public List<Product> getAllProducts() 
{
    // TODO Auto-generated method stub
    // TODO Auto-generated method stub
    // create an iterator for the Arraylist

    if (products.isEmpty())
    {
        return new ArrayList<Product>() ;
    }
    return products;
}

Unfortunately, when I run my test script (tests the interface test class and super-class) the getAllProducts() method is not working the way it should and it is returning a productdb.util.AssertionFailedError: expected:<1> but was:<0> message. Here is the way the test script is testing the getAllProducts() method:

    // testing getAllProducts()
    List<Product> productList = productDB.getAllProducts();     
    int size = productList.size();      
    productList.remove(0);      
    productList = productDB.getAllProducts();       
    Assert.assertEquals(size, productList.size());

Please help me identify my error. Thanks.

6
  • Is the above actual implementation of getAllProducts() or blue rpint? Commented Aug 21, 2015 at 20:43
  • yes the above is the actual implementation of getAllProducts(). Commented Aug 21, 2015 at 20:44
  • overridden method is doing that much only ,checking for empty . Commented Aug 21, 2015 at 20:45
  • PS. in getAllProducts() you have a comment that says 'create an iterator', except the method signature requires returning a List, not Iterator. Commented Aug 21, 2015 at 20:45
  • You remove the single element of the list and then you expect to keep its size? What? You know what references are and how they work? ... Commented Aug 21, 2015 at 20:46

1 Answer 1

2

You return a reference to the ArrayList object. Then you modify the object. Then you get another reference to it and discover that the object was modified.

If you want to protect the data structure from external modification, then return a new List or an UnmodifiableList:

@Override
public List<Product> getAllProducts() 
{
    return new ArrayList<>(products);
}

Or, to avoid extra memory allocation and copies (note that this will cause the call to .remove() in your test code to fail; the important part is whether you must allow callers to modify the list they receive or not):

@Override
public List<Product> getAllProducts() 
{
    return Collections.unmodifiableList(products);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Should I implement the above code as is, i.e remove the if block?
@DeeTee let me ask you: what will be different with and without the if block? : )
I guess either way it is going to return the ArrayList products as is; with or without objects in it...
Correct: the ArrayList constructor will not fail when the provided Collection is empty. So either way you make a new ArrayList that is empty, or has references to each of the elements of the original.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.