java - lists - junit tutorial
Afirmar sobre una lista en Junit (9)
¡No reinventes la rueda!
Hay una biblioteca de Google Code que hace esto por usted: Hamcrest
[Hamcrest] Proporciona una biblioteca de objetos de coincidencia (también conocidos como restricciones o predicados) que permite que las reglas de "coincidencia" se definan declarativamente, para ser utilizadas en otros marcos. Los escenarios típicos incluyen marcos de prueba, bibliotecas burlonas y reglas de validación UI.
¿Cómo hacer afirmaciones sobre una lista en un caso de prueba JUnit ? No solo el tamaño de la lista, sino también el contenido de la lista.
Esta es una respuesta heredada, adecuada para JUnit 4.3 y siguientes. La versión moderna de JUnit incluye un mensaje de error legible incorporado en el método assertThat. Prefiere otras respuestas sobre esta pregunta, si es posible.
List<E> a = resultFromTest();
List<E> expected = Arrays.asList(new E(), new E(), ...);
assertTrue("Expected ''a'' and ''expected'' to be equal."+
"/n ''a'' = "+a+
"/n ''expected'' = "+expected,
expected.equals(a));
Para el registro, como @Paul mencionó en su comentario a esta respuesta, dos List
s son iguales:
si y solo si el objeto especificado también es una lista, ambas listas tienen el mismo tamaño, y todos los pares correspondientes de elementos en las dos listas son iguales. (Dos elementos
e1
ye2
son iguales si(e1==null ? e2==null : e1.equals(e2))
.) En otras palabras, dos listas se definen como iguales si contienen los mismos elementos en el mismo orden . Esta definición asegura que el método equals funciona correctamente en diferentes implementaciones de la interfaz de laList
.
Vea los JavaDocs de la interfaz de la List
.
Me di cuenta de que esto fue preguntado hace un par de años, probablemente esta característica no existía entonces. Pero ahora, es fácil simplemente hacer esto:
@Test
public void test_array_pass()
{
List<String> actual = Arrays.asList("fee", "fi", "foe");
List<String> expected = Arrays.asList("fee", "fi", "foe");
assertThat(actual, is(expected));
assertThat(actual, is(not(expected)));
}
Si tiene instalada una versión reciente de Junit con Hamcrest, simplemente agregue estas importaciones:
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T, org.hamcrest.Matcher)
http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html
http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html
No hago esto, todas las respuestas anteriores dan la solución exacta para comparar dos listas de Objetos. La mayoría de los enfoques anteriores pueden ser útiles para seguir únicamente el límite de comparaciones: comparación de tamaños: comparación de referencias
Pero si tenemos listas del mismo tamaño de objetos y diferentes datos en el nivel de objetos, entonces estos enfoques de comparación no ayudarán.
Creo que el siguiente enfoque funcionará perfectamente con la anulación de iguales y el método hashcode en el objeto definido por el usuario.
Utilicé Xstream lib para anular equals y hashcode pero también podemos anular equals y hashcode por out logics / comparison.
Aquí está el ejemplo para su referencia
import com.thoughtworks.xstream.XStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
class TestClass {
private String name;
private String id;
public void setName(String value) {
this.name = value;
}
public String getName() {
return this.name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
XStream xstream = new XStream();
String oxml = xstream.toXML(o);
String myxml = xstream.toXML(this);
return myxml.equals(oxml);
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
XStream xstream = new XStream();
String myxml = xstream.toXML(this);
return myxml.hashCode();
}
}
public class XstreamCompareTest {
public static void main(String[] args) throws ParseException {
checkObjectEquals();
}
private static void checkObjectEquals() {
List<TestClass> testList1 = new ArrayList<TestClass>();
TestClass tObj1 = new TestClass();
tObj1.setId("test3");
tObj1.setName("testname3");
testList1.add(tObj1);
TestClass tObj2 = new TestClass();
tObj2.setId("test2");
tObj2.setName("testname2");
testList1.add(tObj2);
testList1.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));
List<TestClass> testList2 = new ArrayList<TestClass>();
TestClass tObj3 = new TestClass();
tObj3.setId("test3");
tObj3.setName("testname3");
testList2.add(tObj3);
TestClass tObj4 = new TestClass();
tObj4.setId("test2");
tObj4.setName("testname2");
testList2.add(tObj4);
testList2.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));
if (isNotMatch(testList1, testList2)) {
System.out.println("The list are not matched");
} else {
System.out.println("The list are matched");
}
}
private static boolean isNotMatch(List<TestClass> clist1, List<TestClass> clist2) {
return clist1.size() != clist2.size() || !clist1.equals(clist2);
}
}
Lo más importante es que puede ignorar los campos por Anotación (@XStreamOmitField) si no desea incluir ningún campo en la verificación igual de Objetos. Hay muchas Anotaciones como esta para configurar, así que echa un vistazo profundo a las anotaciones de esta lib.
Estoy seguro de que esta respuesta le ahorrará tiempo para identificar el enfoque correcto para comparar dos listas de objetos :). Comente si ve algún problema al respecto.
No se transforme en una cadena y compare. Esto no es bueno para el rendimiento. En el junit, dentro de Corematchers, hay una coincidencia para this => hasItems
List<Integer> yourList = Arrays.asList(1,2,3,4)
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));
Esta es la mejor manera que conozco para verificar elementos en una lista.
Puede usar assertEquals en junit.
import org.junit.Assert;
import org.junit.Test;
@Test
public void test_array_pass()
{
List<String> actual = Arrays.asList("fee", "fi", "foe");
List<String> expected = Arrays.asList("fee", "fi", "foe");
Assert.assertEquals(actual,expected);
}
Si el orden de los elementos es diferente, devolverá el error.
Si está afirmando una lista de objetos modelo, debe anular el método equals en el modelo específico.
@Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && obj instanceof ModelName) { ModelName other = (ModelName) obj; return this.getItem().equals(other.getItem()) ; } return false; }
Si no le importa el orden de los elementos, recomiendo ListAssert.assertEquals
en junit-addons.
Enlace: http://junit-addons.sourceforge.net/
Para los usuarios perezosos de Maven:
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
si no desea crear una lista de matriz, puede intentar esto también
@Test
public void test_array_pass()
{
List<String> list = Arrays.asList("fee", "fi", "foe");
Strint listToString = list.toString();
Assert.assertTrue(listToString.contains("[fee, fi, foe]")); // passes
}
List<Integer> figureTypes = new ArrayList<Integer>(
Arrays.asList(
1,
2
));
List<Integer> figureTypes2 = new ArrayList<Integer>(
Arrays.asList(
1,
2));
assertTrue(figureTypes .equals(figureTypes2 ));