IronWoods.es

Desarrollo web

Blog / Java / JUnit - Pruebas de objetos equivalentes

Supongamos que tenemos un método que debemos testear que nos devuelve una instancia de una clase, donde lo que importa es el valor de sus propiedades, un objeto de tipo POJO.

Creando las pruebas

Nos interesa saber el valor de las propiedades para una instancia de una clase, es decir, deberemos comprobar la "equivalencia" de dos instancias de la clase. Así, crearemos una instancia de la clase para compararla con la obtenida por el método que estamos testeando.

Si usáramos un sólo assert y dado que ambas instancias son diferentes, aunque los valores de sus propiedades coincidan, este fallará. Debemos plantear las pruebas de manera diferente, lo más sencillo: un assertEquals() por cada propiedad que se requiera comprobar.

Así para testear la clase:

public class Foo {


private String id;

private String name;

private int age;



public Foo( String id, String name, int age ) {

this.id = id;

this.name = name;

this.age = age;

}


// Setters and Getters

// ...


} // class


tendríamos:

assertEquals(

expResult.getId(), result.getId( ));

assertEquals(

expResult.getName(), result.getName( ));

assertEquals(

expResult.getDescription(), result.getDescription( ));


donde result y expResult son instancias de la clase Foo.

Alternativas...

En teoría debe haber un sólo assert por cada método, o "condición", a testear.

Se puede sobrescribir el método equals() de la clase java.lang.Object dentro de Foo, algo inconveniente ya que "ensucia" nuestras clases con código que usaremos sólo para testearlas.

Otra forma de hacerlo, sin tocar el código de las clases del proyecto, es crear en los test una nueva clase para el mock, es decir, crear una clase FooMock que extienda la clase Foo a testear y que situaremos con las clases con las pruebas.

En la clase FooMock sólo se añaden los constructores necesarios y el método equals() sobrescrito.


Código:

public class FooMock extends Foo {


public FooMock( String id, String name, int age ) {

super( id, name, age );

}


@Override

public boolean equals(Object obj) {

Foo foo = (Foo) obj;


return (

((this.getId() == null && foo.getId() == null) ||

this.getId().equals(foo.getId( ))) &&

((this.getName() == null && foo.getName() == null) ||

this.getName().equals(foo.getName( ))) &&

this.getAge() == foo.getAge( ));

}


} // class


Ahora, en la clase FooTest, expResult deberá ser una instancia de FooMock en lugar de una de Foo y sólo se usará un assert para testear el método en cuestión:

assertTrue(

expResult.equals(result));



Nota: esta entrada tiene su origen en la pregunta de StackOverflow: ¿comparar objetos en Java?



19-07-2018