Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to JUnit test that two List<E> contain the same elements in the same order?

Tags:

java

junit

guava

Context

I am writing a simple JUnit test for the MyObject class.

A MyObject can be created from a static factory method that takes a varargs of String.

MyObject.ofComponents("Uno", "Dos", "Tres"); 

At any time during the existence of MyObject, clients can inspect the parameters it was created by in the form of a List<E>, through the .getComponents() method.

myObject.ofComponents(); // -> List<String>: { "Uno", "Dos", "Tres" } 

In other words, a MyObject both remembers and exposes the list of parameters that brought it into existence. More details about this contract:

  • The order of getComponents will be the same as the one chosen for object creation
  • Duplicate subsequent String components are allowed and retained in order
  • Behaviour on null is undefined (other code guarantees no null gets to the factory)
  • There are no ways to alter the list of components after object instantiation

I am writing a simple test that creates a MyObject from a list of String and checks that it can return the same list via .getComponents(). I do this immediately but this is supposed to happen at a distance in a realistic code path.

Code

Here my attempt:


List<String> argumentComponents = Lists.newArrayList("One", "Two", "Three"); List<String> returnedComponents =     MyObject.ofComponents(         argumentComponents.toArray(new String[argumentComponents.size()]))         .getComponents(); assertTrue(Iterables.elementsEqual(argumentComponents, returnedComponents)); 

Question

  • Is Google Guava Iterables.elementsEqual() the best way, provided I have the library in my build path, to compare those two lists? this is something I have been agonizing about; should I use this helper method which goes over an Iterable<E>.. check size and then iterate running .equals().. or any other of the methods that an Internet search suggests? what's the canonical way to compare lists for unit tests?

Optional insights I would love to get

  • Is the method test designed reasonably? I am not an expert in JUnit!
  • Is .toArray() the best way to convert a List<E> to a varargs of E?
like image 600
Robottinosino Avatar asked Sep 19 '12 13:09

Robottinosino


People also ask

How do you check if two lists are equal in JUnit?

Using JUnit We can use the logic below to compare the equality of two lists using the assertTrue and assertFalse methods. In this first test, the size of both lists is compared before we check if the elements in both lists are the same. As both of these conditions return true, our test will pass.

How do you assert two lists are equal?

A simple solution to compare two lists of primitive types for equality is using the List. equals() method. It returns true if both lists have the same size, and all corresponding pairs of elements in both lists are equal.

How do I compare two strings in JUnit?

You should always use . equals() when comparing Strings in Java. JUnit calls the . equals() method to determine equality in the method assertEquals(Object o1, Object o2) .


2 Answers

Why not simply use List#equals?

assertEquals(argumentComponents, imapPathComponents); 

Contract of List#equals:

two lists are defined to be equal if they contain the same elements in the same order.

like image 87
assylias Avatar answered Sep 30 '22 13:09

assylias


I prefer using Hamcrest because it gives much better output in case of a failure

Assert.assertThat(listUnderTest,         IsIterableContainingInOrder.contains(expectedList.toArray())); 

Instead of reporting

expected true, got false

it will report

expected List containing "1, 2, 3, ..." got list containing "4, 6, 2, ..."

IsIterableContainingInOrder.contain

Hamcrest

According to the Javadoc:

Creates a matcher for Iterables that matches when a single pass over the examined Iterable yields a series of items, each logically equal to the corresponding item in the specified items. For a positive match, the examined iterable must be of the same length as the number of specified items

So the listUnderTest must have the same number of elements and each element must match the expected values in order.

like image 42
John B Avatar answered Sep 30 '22 13:09

John B