[JAVA] Avec EqualsVerifier, le test equals () s'est terminé en un instant

introduction

Si vous voulez vérifier l'équivalence des classes en Java, vous devez implémenter correctement ʻequals () et hashCode () `[^ 1]. Normalement, je ne l'implémente pas moi-même, donc je pense qu'il n'y a pas d'erreur, mais je crains de ne pas le tester.

Lorsque je cherchais une méthode efficace, j'ai trouvé une bibliothèque appelée EqualsVerifier [].

Installation

Getting Started décrit comment configurer dans Maven. Pour d'autres outils, consultez Mvn Repository.

Comment utiliser

Par exemple, il existe la classe Name suivante. Ces ʻequals () ʻet` hashCode () ʻ sont automatiquement générés par IntelliJ IDEA.

import java.util.Objects;

public final class Name {
    private final String name;

    public Name of(String name) {
        return new Name(name);
    }

    public Name(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Name name1 = (Name) o;
        return Objects.equals(name, name1.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

Le test pour cela est le suivant (en utilisant JUnit 4.12.

import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.Test;

import java.sql.Timestamp;

public final class EqualsVerifierTest {
    @Test
    public void test_name() {
        EqualsVerifier.forClass(Name.class).verify();
    }
}

Seulement ça. C'est facile.

Bien sûr, je ne sais pas si je l'ai vraiment testé, donc par exemple, je le teste avec la classe Timestamp [], qui ne suit pas le contrat général de ʻequals () `.

EqualsVerifier.forClass(Timestamp.class).verify();

J'ai eu l'erreur suivante.

java.lang.AssertionError: Overloaded: More than one equals method found. Signature should be: public boolean equals(Object obj) For more information, go to: http://www.jqno.nl/equalsverifier/errormessages

Si vous souhaitez exclure certains champs

C'est dans Ignorer les champs, mais vous pouvez l'exclure, par exemple: Consultez la documentation pour plus de détails.

Je pense qu'il vaut mieux utiliser transitoire pour moi-même.

Principe de fonctionnement

Il est écrit en bas de Pourquoi, quoi, comment?, mais c'est grosso modo comme suit. C'est un peu de magie noire.

  1. Comme pour le framework de simulation, créez une instance sans appeler de constructeur.
  2. Utilisez la réflexion pour définir la valeur dans le champ.
  3. Vérifiez si ʻequals () ʻethashCode ()obtiennent les résultats attendus pour ceux-ci.
  4. Examinez la signature de la méthode ʻequals () `pour vous assurer que vous utilisez des remplacements au lieu de surcharges.

en conclusion

J'ai pensé que c'était important de passer un bon moment (´ω`)

[^ 1]: En vigueur Java 2nd Edition Voir "Point 8 Respecter le contrat général en cas de remplacement égal" et "Point 9 Toujours remplacer le hashCode lors du remplacement égal".

Recommended Posts

Avec EqualsVerifier, le test equals () s'est terminé en un instant
J'étais accro au test Spring-Batch
Tester le contenu d'un fichier Excel avec JUnit
Test d'intégration avec Gradle
[Rails] Test avec RSpec
Testez Nokogiri avec Rspec.
Tester automatiquement avec la jauge
Test de charge avec JMeter
Faites un test unitaire avec Junit.
Ce à quoi j'étais accro avec l'API REST Redmine