web-dev-qa-db-fra.com

Junit Test des variables Setters et Getters of Instance

Lors de la création de cas de test pour les setters et les getters de variables d'instance dans l'objet. Quelle est la meilleure approche? Ici, j'utilise les méthodes get et set dans mes tests. Serait-ce une mauvaise stratégie de test?

/**
 * Test of setFlightNumber method, of class Flight.
 */
@Test
public void testSetFlightNumber() {
    System.out.println("setFlightNumber");
    int flightNumber = 1000;
    Flight instance = new Flight();
    instance.setFlightNumber(flightNumber);
    // TODO review the generated test code and remove the default call to fail.
    assertEquals(instance.getFlightNumber(), flightNumber);
}

/**
 * Test of getFlightNumber method, of class Flight.
 */
@Test
public void testGetFlightNumber() {
    System.out.println("getFlightNumber");
    Flight instance = new Flight();
    int expResult = 1000;
    instance.setFlightNumber(1000);
    int result = instance.getFlightNumber();
    assertEquals(expResult, result);
}
12
user3126529

Le principe de base des tests unitaires est que vous testez un simple unité de code; c'est-à-dire que chaque méthode doit être testée sur ses propres mérites.

Cela signifie que nous ne pouvons pas utiliser la méthode get dans notre test set et vice-versa - vous ne testez pas l'unité de code individuelle qui constitue la méthode unique.

Étant donné que...

Supposons que nous ayons une PlainOldJavaObject avec un champ value pour laquelle nous souhaitons (pour une raison quelconque) tester la validité des setters et des getters. Le seul moyen approprié de le faire est d'utiliser l'utilisation de la réflexion .

Voici ma déclaration de classe, qui est assez maigre:

public class PlainOldJavaObject {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

Je configure maintenant ma classe de test pour utiliser la réflexion; en utilisant spécifiquement la classe Field:

public class PlainOldJavaObjectTest {

    @Test
    public void testSetter_setsProperly() throws NoSuchFieldException, IllegalAccessException {
        //given
        final PlainOldJavaObject pojo = new PlainOldJavaObject();

        //when
        pojo.setValue("foo");

        //then
        final Field field = pojo.getClass().getDeclaredField("value");
        field.setAccessible(true);
        assertEquals("Fields didn't match", field.get(pojo), "foo");
    }

    @Test
    public void testGetter_getsValue() throws NoSuchFieldException, IllegalAccessException {
        //given
        final PlainOldJavaObject pojo = new PlainOldJavaObject();
        final Field field = pojo.getClass().getDeclaredField("value");
        field.setAccessible(true);
        field.set(pojo, "magic_values");

        //when
        final String result = pojo.getValue();

        //then
        assertEquals("field wasn't retrieved properly", result, "magic_values");
    }

}

Dans le premier test, je m'assure que le champ est lu en accédant de manière réfléchie à la valeur contenue dans le champ pour l'instance de PlainOldJavaObject. Sans violer l'intégrité de la classe déclarée *, je suis convaincu que le champ est défini correctement.

Dans le deuxième test, je suppose que la valeur a déjà été définie sur une valeur antérieure. La configuration implique donc de renseigner le champ avec une valeur par défaut connue. Lorsque je relis la valeur, j'affirme que la valeur lue est la valeur pour laquelle nous savons qu'elle a été définie à l'origine.

En fin de compte, si vous avez beaucoup de setters et de getters, vous devrez utiliser un code comme celui-ci (puisque les cas peuvent ne sont pas valides).

*: Remarquez que la réflexion est un moyen rapide et rapide d’avoir des problèmes extrêmes avec un comportement indéfini et que vous n’avez que peu de garanties d’immuabilité des objets. Vous vous débarrassez de la langue et faites des choses étranges et inhabituelles. Procédez à vos risques et périls.

19
Makoto

Utiliser l'API Bean Runner

Ceci testera automatiquement tous les getters et les setters en s'assurant que les valeurs sont correctement définies.

testBean

public void testBean(Java.lang.Object bean)
              throws Java.lang.Exception
Test the properties that have both getters and setters. Exclude those who have been excluded by excludeProperty(String). If the object implements Serializable, do a check to ensure it really is.
Parameters:
bean - the object to test
Throws:
Java.lang.Exception - on failure
1
user6123723

Je crois que les tests de getter/setter ont une valeur en ce sens qu’ils peuvent détecter les fautes de frappe. Cependant, il faut y consacrer très peu de temps car ces erreurs ne sont pas fréquentes en raison des outils de génération de code. Par conséquent, utiliser un outil pour exécuter ces tests plutôt que de les écrire vous-même est une bonne pratique.

C'est pourquoi j'ai créé une ReflectiveGetterSetterTester qui a une méthode testAllGetterSetters

ReflectiveGetterSetterTester

Couple d'autres notes ... 

  • Il n'est pas nécessaire d'utiliser deux méthodes de test. Utilisez-en un car il exercera à la fois le getter et le setter.
  • Pensez à utiliser une Theory pour tester une plage de valeurs valides (0, 1, Integer.MAX_VALUE). Vous pouvez également utiliser TestedOn pour transmettre ceux-ci en ligne exemple ici
  • Testez les conditions d'erreur telles que le passage de -1
0
John B