Damon Julian
Damon Julian

Reputation: 3999

how to write unit test for retrieving items from a java Set

I have implemented a ShoppingCart where the CartItems are put in a Set to avoid duplicate items. I want to test putting items in cart and persisting in db, and then retrieving the items from cart and checking if they were the same .

I tried to do this as below, but it looks ugly. It will work only for a single item. The problem would have been solved if a List was used to store CartItems.

class ShoppingCart{
   private Set<CartItem> cartItems;
   private User customer;
   public ShoppingCart(User customer) {
    super();
    this.cartItems = new TreeSet<CartItem>();
    this.customer = customer;
   }
   ...
}

class CartItem{
   private Product pdt;
   private int quantity;
   ...
}

unit test

User bob = getUserByName("bob");
CartItem citem1 = new CartItem(product1,3);
ShoppingCart cart = new ShoppingCart(bob);
cart.addItem(citem1);
cart.saveToDB();
ShoppingCart bobCart = getCartFromDbUsingCustomer(bob);
assertNotNull(bobCart);
Set<CartItem> bobCartItems = bobCart.getCartItems();
assertEquals(1,bobCartItems.size());
CartItem[] citems = bobCartItems.toArray(new CartItem[0]);
CartItem bobCartItem = citems[0];
assertEquals("978",bobCartItem.getProduct().getIsbn());
assertEquals(3,bobCartItem.getQuantity());

This would only work if a single cart item is added to the cart.If two or more cartItems are added, I will be able to retireve the items only if some kind of comparator is used. I have a feeling that, this is not quite the right way to do this.

Any suggestions?

Upvotes: 1

Views: 243

Answers (3)

Morten
Morten

Reputation: 3854

Sounds like your shoppingcart is doing an awful lot -- businesslogic AND database stuff. If you separated concerns into different classes, your testing job would become much easier. A unittest talking to a database is never a good thing.

Upvotes: 1

DaveFar
DaveFar

Reputation: 7467

Testing sets should not be a problem.

If you want to test your complete set, create an equal one and use the equals() method on the two sets. Be sure that the elements in the set also implement equals().

If you do not want to test your complete set, you can either access it programmatically, or use hamcrest matchers, e.g. hasItem()/hasItems()/anyOf()/allOf(). I highly recommend hamcrest for testing anyways, because of more concise tests, better readable tests, and better readable test failures.

Upvotes: 3

JB Nizet
JB Nizet

Reputation: 692073

There are basically two ways of doing it:

  • transform the set into a list using a deterministic order, and test if all items in the list are the expected items. You will indeed need a comparator.
  • use some predicate and test if any item in the set satisfies the predicate. Guava might be useful here with its Predicate class and its Iterables.any method.

Upvotes: 1

Related Questions