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);
}
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.
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
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
Couple d'autres notes ...
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-1