Tutoriel pour apprendre à tester ses beans Java avec Pojo-Tester en 5 minutes

Pojo-Tester est une bibliothèque dédiée aux tests de vos beans simples. Elle permet d'augmenter efficacement la couverture de code, là où c'est généralement laborieux. L'objectif de cet article est de mettre en action les capacités principales de Pojo-Tester, en cinq minutes chrono. Commentez Donner une note à l'article (5)

Article lu   fois.

L'auteur

Site personnelICAUDA

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Nos programmes utilisent de nombreux POJO : Plain Old Java Objects. Ces beans très simples sont généralement constitués d'attributs privés, parfois marqués "final", qu'on manipule via des getters et des setters. Pour des raisons pratiques, certains sont équipés de constructeurs reprenant les-dits attributs, en plus du constructeur par défaut. Et pour compléter le tout, on leur ajoute souvent les méthodes equals, hashCode et toString, héritées de Object.

La plupart des IDE (Eclipse, Idea, etc.) permettent d'ajouter toutes ces méthodes (getters, setters, constructeurs, equals, hashCode et toString) aux beans en quelques clics, si bien que la plupart des développeurs considèrent les POJO comme des beans de second plan. On les croit fiables. On n'y prête pas attention. On les ignore même dans les tests. C'est bien entendu une erreur, car de nombreux problèmes peuvent en résulter, mais qui lancera la première pierre ?

La bibliothèque Pojo-Tester, sous license GNU GPL 3, s'intéresse spécifiquement à ces beans. Elle offre des mécanismes simples et efficaces pour les tester de fond en comble.

Pourquoi allez-vous donc utiliser Pojo-Tester ? À quoi cette bibliothèque va-t-elle vous servir ? D'abord à augmenter le score de votre couverture de code, même si c'est superficiel. Ensuite, et surtout, à sécuriser les méthodes de vos beans qui serait quasiment intestables sans. Pensez, par exemple, aux mauvais copiés-collés dans vos getters/setters ou dans l'enchaînement d'égalité de la méthode equals. Considérez aussi l'ajout d'un attribut, après coup, qui aurait été pris en compte dans equals, mais oublié dans hashCode. C'est une véritable galère de d'identifier ce genre de bogue…

II. Projet d'exemple

Voici quelques éléments vraiment triviaux qui vont nous permettre d'illustrer le fonctionnement de la bibliothèque Pojo-Tester à moindre coût. Les codes complets sont proposés en annexes. Le projet dvp-article-pojo-tester est également disponible sur GitHub.

II-A. Bean et service

Pour commencer, disons que nous avons un bean Chien contenant quelques attributs (cf. ci-dessous). Pour faire bonne mesure, on demande à Eclipse de générer les méthodes hashCode, equals et toString, ainsi que les getters et les setters :

Chien.java
Sélectionnez

public class Chien {

    private String name;
    private String race;
    private double poids; // Poids en kg
    private double taille; // Taille exprimee en metre
    private Date dateNaissance;
    private List<String> couleurs;
    
    public Chien() {
    }
    
    // + Getters / Setters
    // + hashCode / equals
    // + toString
    ...

Juste pour l'exemple, disons qu'on écrit ChienService, une classe proposant un ensemble de fonctionnalités liées aux chiens.

ChienService.java
Sélectionnez

public class ChienService {

    public int calculerIMC(final Chien chien) {
        return (int) (chien.getPoids() / Math.pow(chien.getTaille(), 2));
    }
    
    ...

II-B. Maven

Dans notre projet Maven, on indique une dépendance vers JUnit puisqu'on va écrire des tests.

Java 8 et JUnit dans pom.xml
Sélectionnez

<project ...>
    ...
    
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

On ajoute aussi une dépendance vers Jacoco, une bibliothèque (similaire à Cobertura) permettant de mesurer la couverture de code de notre programme.

Couverture avec Jacoco dans pom.xml
Sélectionnez

<project ...>
    ...
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.9</version>

                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <rule implementation="org.jacoco.maven.RuleConfiguration">
                                    <element>BUNDLE</element>
                                    <limits>
                                        <limit implementation="org.jacoco.report.check.Limit">
                                            <counter>COMPLEXITY</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>0.70</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Cette configuration indique qu'on attend une couverture d'au moins 70 %, faute de quoi le build Maven se terminera en erreur.

II-C. Tests évidents

Pour tester convenablement l'objet Chien, il ne faudrait pas moins de huit tests. Pour l'instant on va donc seulement se concentrer sur le service. Voici le genre de test qu'on pourrait écrire :

ChienServiceTest.java
Sélectionnez

public class ChienServiceTest {

    private ChienService chienService = new ChienService();

    @Test
    public void testCalculerIMCMilou() {
        // Arrange
        final double taille = 0.39;
        final double poids = 9;
        final int expectedIMC = 59;

        // Arrange obj
        final Chien milou = new Chien();
        milou.setTaille(taille);
        milou.setPoids(poids);

        // Act
        final int imc = chienService.calculerIMC(milou);

        // Assert
        Assert.assertEquals(expectedIMC, imc);
    }

C'est le formalisme AAA (Arrange, Act and Assert), si cher à votre serviteur, qui est utilisé ici.

Voici, ci-dessous, les rapports de Jacoco à propos de la couverture du code à ce stade :

Image non disponible
Image non disponible
Image non disponible

III. Action

On va maintenant s'occuper des POJO de notre programme.

III-A. Ajouter Pojo-Tester

Pour commencer, on ajoute la dépendance à Pojo-Tester :

Pojo-Tester dans pom.xml
Sélectionnez

<project ...>
    ...

    <dependencies>
        ...
        
        <dependency>
            <groupId>pl.pojo</groupId>
            <artifactId>pojo-tester</artifactId>
            <version>0.7.5</version>
        </dependency>
    </dependencies>

On aura également besoin de préciser le repository où trouver la bibliothèque Pojo-Tester :

Repository de Pojo-Tester dans pom.xml
Sélectionnez

<project ...>
    ...
    
    <repositories>
        <repository>
            <id>jcenter</id>
            <url>http://jcenter.bintray.com/</url>
        </repository>
    </repositories>

III-B. Bean classique : Chien

Le bean Chien, qui représente sans aucun doute le cas le plus classique, est facile à tester :

Test du bean Chien dans AnimalTest.java
Sélectionnez

import static pl.pojo.tester.api.assertion.Assertions.assertPojoMethodsFor;

public class AnimalTest {

    @Test
    public void testPojoChien() {
        // Arrange
        final Class<?> classUnderTest = Chien.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

Voici, ci-dessous, ce que ça donne au niveau de la couverture du code avec Jacoco. On constate que toutes les méthodes ont bien été couvertes (avec un petit raté sur equals). Magique, facile ?

Image non disponible
Image non disponible

À cette date, la bibliothèque a encore du mal a bien tester ma méthode equals. Il reste des instructions non couvertes. Espérons que les futures versions fassent évoluer le sujet.

Ajoutons maintenant le nouvel attribut « méchant » au bean Chien et demandons à Eclipse d'en générer le getter et le setter. Ici on va faire exprès d'oublier de faire évoluer equals, hashCode et toString.

Ajout de mechant dans Chien.java
Sélectionnez

public class Chien {
    ...

    private boolean mechant; // juste getter/setter
    
    ...
    
    public boolean isMechant() {
        return mechant;
    }

    public void setMechant(boolean mechant) {
        this.mechant = mechant;
    }

Là, Pojo-Tester va nous rappeler à l'ordre ; un oubli est vite arrivé et peut passer longtemps inaperçu. Charge ensuite au développeur de choisir quoi faire en piochant dans les techniques abordées dans les prochains chapitres.

Erreur
Sélectionnez

Class com.dvp.tld.article.pojotester.domaine.Chien has bad 'toString' method implementation.
The toString method should contain:
mechant=false
But does not.
Result of toString:
Chien [name=null, race=null, poids=0.0, taille=0.0, dateNaissance=null, couleurs=null]

III-C. Bean immutable : Lapin

Ajoutons maintenant le bean Lapin ayant la particularité de posséder des attributs marqués "final". Ça change quelque peu la donne.

Lapin.java
Sélectionnez

public class Lapin {

    // Attributs final
    private final String name;
    private final int age;
    
    // + Getters
    // + hashCode / equals
    // + toString
    ...

Le bean Lapin n'a pas de setter puisque tous ses attributs sont "final".

Essayons d'appliquer la même stratégie que pour le bean Chien :

Test du bean Lapin dans AnimalTest.java
Sélectionnez

public class AnimalTest {

    @Test
    public void testPojoLapinFailed() {
        // Arrange
        final Class<?> classUnderTest = Lapin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

Le test échoue naturellement puisque Pojo-Tester ne trouve pas de setter :

Message d'erreur
Sélectionnez

Tests in error: 
  testPojoLapinFailed(...AnimalTest): Class ...Lapin has no setter for field private final ...String ...Lapin.name

Les noms de classes et d'attributs ont été tronqués dans le message d'erreur ci-dessus pour en faciliter la lecture.

Il faut donc préciser les méthodes qu'on souhaite tester :

Test du bean Lapin dans AnimalTest.java
Sélectionnez

import static pl.pojo.tester.api.assertion.Method.CONSTRUCTOR;
import static pl.pojo.tester.api.assertion.Method.EQUALS;
import static pl.pojo.tester.api.assertion.Method.GETTER;
import static pl.pojo.tester.api.assertion.Method.HASH_CODE;
import static pl.pojo.tester.api.assertion.Method.SETTER;
import static pl.pojo.tester.api.assertion.Method.TO_STRING;

public class AnimalTest {

    @Test
    public void testPojoLapin() {
        // Arrange
        final Class<?> classUnderTest = Lapin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();
    }

Ici, EQUALS et HASH_CODE sont sur la même ligne (dans la même instruction) pour insister sur le fait que les deux méthodes associées fonctionnent en paire. Elles doivent respecter le même contrat. Par extension, cela doit se traduire aussi dans les tests.

Et là ça fonctionne, comme on peut le voir sur le rapport de Jacoco :

Image non disponible

III-D. Bean semi-immutable : Chat

On va compliquer encore les choses avec le bean Chat dans lequel seuls les attributs "name" et "age" sont pris en compte pour le constructeur et les méthodes hashCode et equals :

Chat.java
Sélectionnez

public class Chat {

    // Attributs principaux (dans cons, hashcode et equals)
    private final String name;
    private final int age;

    // Attributs en plus
    private double poids;
    private String moustache;
    private String[] petits;

    public Chat(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    // + Getters / Setters
    // + hashCode / equals
    // + toString
    ...

Si on tente de tester Chat comme on l'avait fait avec Lapin, ça ne va évidement pas être bon :

Test du bean Chat dans AnimalTest.java
Sélectionnez

public class AnimalTest {

    @Test
    public void testPojoChatFailed() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

    }

Le build Maven va en effet nous donner l'erreur suivante, indiquant que la méthode hashCode n'est pas correcte. Notez que le test s'arrête à la première erreur sans rien dire des éventuelles autres erreurs :

Message d'erreur
Sélectionnez

Class ...Chat has bad 'hashCode' method implementation.
The hashCode method should return different hash codes for non equal objects.
Current implementation returns same hash codes.
Object:
Chat [name=www.pojo.pl, age=-4, poids=0.0, moustache=null, petits=null]
and
Chat [name=www.pojo.pl, age=-4, poids=-2.5, moustache=null, petits=null]
should have different hash codes:
1122311828
and
1122311828

Il faut donc préciser les attributs qu'on souhaite prendre en compte pour chaque méthode, ce qui donne lieu à plusieurs appels dans le test. Ici on parlera d'inclusion :

Test du bean Chat par inclusion dans AnimalTest.java
Sélectionnez

import static pl.pojo.tester.api.FieldPredicate.include;

public class AnimalTest {

    @Test
    public void testPojoChatInclude() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest, include("name", "age")) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest, include("poids", "moustache", "petits")) //
                .testing(SETTER) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .areWellImplemented();
    }

Ce n'est pas très pratique de fonctionner par inclusion. La bibliothèque permet aussi de travailler par exclusion :

Test du bean Chat par exclusion dans AnimalTest.java
Sélectionnez

import static pl.pojo.tester.api.FieldPredicate.include;

public class AnimalTest {

    @Test
    public void testPojoChatExclude() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest, exclude("poids", "moustache", "petits")) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest, exclude("name", "age")) //
                .testing(SETTER) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .areWellImplemented();
    }

Bien entendu, rien n'empêche de travailler à fois par inclusion et par exclusion, si cela vous semble plus simple.

Les auteurs de Pojo-Tester conseillent de privilégier les exclusions. Pourquoi ça ? Disons qu'on ajoute un attribut au bean mais qu'on oublie d'en tenir compte dans la méthode equals. Dans ce cas, la bibliothèque va s'en rendre compte si on travaille par exclusion. Au contraire, si on a oublié l'attribut dans equals, il est plus que probable qu'on l'aura aussi oublié dans inclusions, CQFD…

III-E. Dauphin Lombok : Dauphin

Si, comme votre serviteur, vous aimez la bibliothèque Lombok, vous serez content d'apprendre que Pojo-Tester saura gérer. Mais ajoutons d'abord Lombok à la liste de nos dépendances :

Lombok dans pom.xml
Sélectionnez

<project ...>
    ...

    <dependencies>
        ...
        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
        </dependency>
    </dependencies>

Ici on va simplement annoter le bean Dauphin avec @Data, qui génère toute la série des méthodes qu'on a déjà utilisées dans le reste de cet article.

Dauphin.java
Sélectionnez

import lombok.Data;

@Data
public class Dauphin {

    private String name;
    private int speed;

Au niveau du test de Dauphin, on se contente de recopier le test classique qu'on avait écrit pour Chien :

Test du bean Dauphin dans AnimalTest.java
Sélectionnez

import static pl.pojo.tester.api.FieldPredicate.include;

public class AnimalTest {

    @Test
    public void testPojoDauphin() {
        // Arrange
        final Class<?> classUnderTest = Dauphin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

Et ça marche du premier coup, comme l'atteste le rapport Jacoco.

Image non disponible
Image non disponible
Image non disponible

IV. Conclusion

Une fois n'est pas coutume, le contrat d'un article en cinq minutes est presque rempli. Il faut dire que le sujet semblait simple, du moins en apparence. Il est toutefois bien plus riche qu'on ne le pense au premier contact. La bibliothèque Pojo-Tester est ce genre d'outil qu'on ajoute à sa collection pour un besoin ponctuel et qui devient rapidement un incontournable, voire un irremplaçable.

Pojo-Tester se présente clairement comme un outil de test mais la plupart des développeurs, y compris votre serviteur, vont initialement l'utiliser pour augmenter leur score de couverture. Il faut avouer qu'un score élevé fait toujours plaisir. Pour en obtenir un, de nombreux projets vont d'ailleurs tout simplement ignorer les POJO, qu'on considère généralement comme dénués de risque et/ou d'une importance secondaire. Même si c'est vrai au lancement du projet, cela devient une erreur avec le temps. En effet, qui n'a jamais été confronté à un bogue issu d'un mauvais copié-collé dans un getter/setter ou un attribut ajouté après coup au bean, mais oublié dans le equals/hashCode ? Ce genre de bogue est facile à corriger mais hyperdifficile à identifier, ce qui fait perdre beaucoup de temps. La bibliothèque Pojo-Tester permet de s'en prémunir.

Pojo-Tester souffre néanmoins de quelques manques. On a déjà parlé de la méthode equals pour laquelle la couverture n'est pas complète. Gageons que cela sera amélioré avec le temps. Même ainsi, c'est une bibliothèque qu'on ne pourrait que conseiller d'avoir dans votre boîte à outils.

Vos retours et remarques nous aident à améliorer les publications de Developpez.com. N'hésitez donc pas à commenter cet article. Commentez Donner une note à l'article (5)

V. Remerciements

J'adresse mes remerciements aux auteurs de la bibliothèque Pojo-Tester. Merci de l'avoir créé et de la maintenir. Elles aide de nombreux développeurs à travers le monde.

Merci également à tous ceux qui ont contribué à la rédaction de cet article : Mickael Baron, jacques_jean et Winjerome.

VI. Annexes

VI-A. Liens

Projet dvp-article-pojo-tester sur GitHub : https://github.com/thierryler/dvp-article-pojo-tester

Pojo-Tester : http://www.pojo.pl/

Jacoco : http://www.eclemma.org/jacoco/

Lombok : https://projectlombok.org/

Mes autres articles : http://thierry-leriche-dessirier.developpez.com/

VI-B. Codes entiers

Chien.java
Sélectionnez

package com.dvp.tld.article.pojotester.domaine;

import java.util.Date;
import java.util.List;

public class Chien {

    private String name;
    private String race;
    private double poids; // Poids en kg
    private double taille; // Taille exprimee en metre
    private Date dateNaissance;
    private List<String> couleurs;
    
    // private boolean mechant; // juste getter/setter

    public Chien() {
        // Rien
    }

    @Override
    public String toString() {
        return "Chien [name=" + name + ", race=" + race + ", poids=" + poids + ", taille=" + taille + ", dateNaissance="
                + dateNaissance + ", couleurs=" + couleurs + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((couleurs == null) ? 0 : couleurs.hashCode());
        result = prime * result + ((dateNaissance == null) ? 0 : dateNaissance.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        long temp;
        temp = Double.doubleToLongBits(poids);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((race == null) ? 0 : race.hashCode());
        temp = Double.doubleToLongBits(taille);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Chien other = (Chien) obj;
        if (couleurs == null) {
            if (other.couleurs != null)
                return false;
        } else if (!couleurs.equals(other.couleurs))
            return false;
        if (dateNaissance == null) {
            if (other.dateNaissance != null)
                return false;
        } else if (!dateNaissance.equals(other.dateNaissance))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (Double.doubleToLongBits(poids) != Double.doubleToLongBits(other.poids))
            return false;
        if (race == null) {
            if (other.race != null)
                return false;
        } else if (!race.equals(other.race))
            return false;
        if (Double.doubleToLongBits(taille) != Double.doubleToLongBits(other.taille))
            return false;
        return true;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public double getPoids() {
        return poids;
    }

    public void setPoids(double poids) {
        this.poids = poids;
    }

    public double getTaille() {
        return taille;
    }

    public void setTaille(double taille) {
        this.taille = taille;
    }

    public Date getDateNaissance() {
        return dateNaissance;
    }

    public void setDateNaissance(Date dateNaissance) {
        this.dateNaissance = dateNaissance;
    }

    public List<String> getCouleurs() {
        return couleurs;
    }

    public void setCouleurs(List<String> couleurs) {
        this.couleurs = couleurs;
    }
    
//    public boolean isMechant() {
//        return mechant;
//    }
//
//    public void setMechant(boolean mechant) {
//        this.mechant = mechant;
//    }

}
Lapin.java
Sélectionnez

package com.dvp.tld.article.pojotester.domaine;

public class Lapin {

    // Attributs final
    private final String name;
    private final int age;

    public Lapin(final String name, final int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Lapin other = (Lapin) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Lapin [name=" + name + ", age=" + age + "]";
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
Cat.java
Sélectionnez

package com.dvp.tld.article.pojotester.domaine;

import java.util.Arrays;

public class Chat {

    // Attributs principaux (dans cons, hashcode et equals)
    private final String name;
    private final int age;

    // Attributs en plus
    private double poids;
    private String moustache;
    private String[] petits;

    public Chat(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Chat [name=" + name + ", age=" + age + ", poids=" + poids + ", moustache=" + moustache + ", petits="
                + Arrays.toString(petits) + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Chat other = (Chat) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public double getPoids() {
        return poids;
    }

    public void setPoids(double poids) {
        this.poids = poids;
    }

    public String getMoustache() {
        return moustache;
    }

    public void setMoustache(String moustache) {
        this.moustache = moustache;
    }

    public String[] getPetits() {
        return petits;
    }

    public void setPetits(String[] petits) {
        this.petits = petits;
    }

}
Dauphin.java
Sélectionnez

package com.dvp.tld.article.pojotester.domaine;

import lombok.Data;

@Data
public class Dauphin {

    private String name;
    private int speed;

}
AnimalTest.java
Sélectionnez

package com.dvp.tld.article.pojotester.domaine;

import static pl.pojo.tester.api.FieldPredicate.exclude;
import static pl.pojo.tester.api.FieldPredicate.include;
import static pl.pojo.tester.api.assertion.Assertions.assertPojoMethodsFor;
import static pl.pojo.tester.api.assertion.Method.CONSTRUCTOR;
import static pl.pojo.tester.api.assertion.Method.EQUALS;
import static pl.pojo.tester.api.assertion.Method.GETTER;
import static pl.pojo.tester.api.assertion.Method.HASH_CODE;
import static pl.pojo.tester.api.assertion.Method.SETTER;
import static pl.pojo.tester.api.assertion.Method.TO_STRING;

import org.junit.Ignore;
import org.junit.Test;

public class AnimalTest {

    @Test
    public void testPojoChien() {
        // Arrange
        final Class<?> classUnderTest = Chien.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

    @Ignore
    @Test
    public void testPojoLapinFailed() {
        // Arrange
        final Class<?> classUnderTest = Lapin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

    @Test
    public void testPojoLapin() {
        // Arrange
        final Class<?> classUnderTest = Lapin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();
    }

    @Test
    @Ignore
    public void testPojoChatFailed() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

    }

    @Test
    public void testPojoChatInclude() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest, include("name", "age")) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest, include("poids", "moustache", "petits")) //
                .testing(SETTER) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .testing(TO_STRING) //
                .areWellImplemented();
    }

    @Test
    public void testPojoChatExclude() {
        // Arrange
        final Class<?> classUnderTest = Chat.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest, exclude("poids", "moustache", "petits")) //
                .testing(EQUALS, HASH_CODE) //
                .testing(CONSTRUCTOR) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest, exclude("name", "age")) //
                .testing(SETTER) //
                .areWellImplemented();

        assertPojoMethodsFor(classUnderTest) //
                .testing(GETTER) //
                .areWellImplemented();
    }

    @Test
    public void testPojoDauphin() {
        // Arrange
        final Class<?> classUnderTest = Dauphin.class;

        // Act

        // Assert
        assertPojoMethodsFor(classUnderTest) //
                .areWellImplemented();
    }

}

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Thierry-Leriche-Dessirier. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.