poniedziałek, 28 marca 2011

Testowanie equals i hashCode

Zgodnie z obecną modą na wszechobecne testy jednostkowe wypadałoby jakoś testować nasze implementacje equals() i hashCode(), żeby się przy tym zbytnio nie narobić proponuję następujące rozwiązanie: klasa abstrakcycja, która sprawdza podstawowe warunki konktraktu dla equals() i hashCode() na podstawie 3 dostarczonych przez klasę dziedziczącą obiektów, które powinnym być identyczne wg. equals (ale maksymalnie od siebie różne) oraz jednego, który jest różny od pozastałych wg. equals. Pełny kod źródłowy wraz z klasą abstrakcyjną można pobrać korzystając z tego linku. Zastosowanie najlepiej widać na przykładzie:

Klasa testowana:
public class Entity {
    
    private int field1;
    private int field2;
    private int notSignificantField;
    
    @Override
    public int hashCode() {
         ...
    }
    
    @Override  
    public boolean equals(Object object) {  
        ...
    }

    public Entity(int field1, int field2, int notSignificantField) {
        this.field1 = field1;
        this.field2 = field2;
        this.notSignificantField = notSignificantField;
    }
    ...
} 

Klasa testująca:
public class EntityTest extends AbstractEqualsTest<Entity> {

    @Override
    public Entity objectThatShouldBeEqualA() {
        return new Entity(1, 2, 33);
    }

    @Override
    public Entity objectThatShouldBeEqualB() {
        return new Entity(1, 2, 44);
    }

    @Override
    public Entity objectThatShouldBeEqualC() {
        return new Entity(1, 2, 55);
    }

    @Override
    public Entity objectThatShouldNotBeEqual() {
        return new Entity(1, 1, 33);
    }
}

3 komentarze:

  1. Szybkie pytanie i Google sugeruje co najmniej dwie gotowe biblioteki: Unitils i openpojo. Bardzo chetnie zobaczylbym, jak sprawdzaja sie ww. (i podobne) biblioteki.

    OdpowiedzUsuń
  2. pytanie filozoficzno-programistyczne: czy w ogóle warto to testować jeżeli IDE sam stworzy metody hashCode/equals a Ty tylko musisz wskazać mu które pola ma brać pod uwagę?

    OdpowiedzUsuń
  3. Można spytać, czy w ogóle warto testować większość rzeczy. Generalnie uważam, że czasami warto napisać testa nawet dla pierdołowatej metody (a equals jest dość istotną metodą), bo wtedy jak przychodzi ktoś inny, zmienia i test się sypie, to znak, że może jednak przesadził.

    OdpowiedzUsuń