Page 1 sur 1

TP8 - Question 3 : Quelques informations ?

Publié : 21 déc. 2017 1:20
par franck.pascutti
Bonsoir,

Je suis en train de faire le TP8 et je me retrouve bloqué sur la question 3.

J'ai bien téléchargé le projet "assertions_et_decorateur.jar" et modifié la classe "NombrePrePost" du package "nombre_exemple" comme je pensais qu'elle devait être.

Globalement, j'ai modifié les méthodes appelées avant chaque modification ("pre_setValeur", "pre_inc" et "pre_dec") afin de déclencher un "assert" si la modification n'était pas valide (hors des limites du nombre).

De même j'ai modifié les méthode appelées après chaque modification ("post_setValeur", "post_inc" et "post_dec") afin de déclencher un "assert" si le nombre résultant n'était pas celui attendu.

Il ne m'a pas semblé bon de modifier "pre_getValeur" et "post_getValeur". La méthode "getValeur" étant un simple accesseur je ne vois pas quelles assertions auraient du sens.

Mon problème est qu'en faisant ceci j'ai cassé le test unitaire "testNombre" car il se produit une assertion plutôt que l'exception "RuntimeException" attendue.
De même, le test unitaire "testNombrePrePost" échoue sans avoir fait appel à aucun code modifié.

Il me semble donc que je n'ai pas compris la question posée ici.
Pouvez-vous détailler un peu plus le rôle attendu de la classe "NombrePrePost" ?

Merci,
Franck Pascutti

Re: TP8 - Question 3 : Quelques informations ?

Publié : 21 déc. 2017 17:54
par Douin
Bonjour,

NombrePrePost décore chaque méthode des vérifications avant leur appel (pré-conditions) et après (post-conditions)

Une exception ne doit pas échouer lors des pré et post elle doit être vérifiée également, ce sera à la méthode originale de lever l'exception, ce sont les diapositives 29 à 34 je peux les compléter si nécessaire

bons tests

Re: TP8 - Question 3 : Quelques informations ?

Publié : 21 déc. 2017 20:29
par Alban_lp
Bonjour Franck

Je suis sur cette question et pour moi les "testNombre" passe correctement mais je n'ai codé que les post, je ne vois pas trop quoi mettre dans les "pre_setValeur", "pre_inc" et "pre_dec"…
C'est peut-être pour ça que mon test marche, j'ai laissé "true" !

Par contre pour "testNombrePrePost", il y a un os. Comment tester avant un appel du constructeur, la question est coton… le commentaire du code laisse penser qu'il faut remonter au constructeur… peut-être que le nombre en parametre devrait être une instance de NombreI et le tester avec un get.class ?
Je creuse…

Par contre il n'y a pas de "submit test" pour cette question ?

@+
Alban

Re: TP8 - Question 3 : Quelques informations ?

Publié : 22 déc. 2017 1:56
par franck.pascutti
Bonsoir Bonsoir à tous,

Tout d'abord merci pour vos réponses qui m'ont permis d'avancer même si je ne suis pas sûr d'avoir bien répondu.

Comme toi Alban j'ai fini par ne pas faire de préconditions pour ces méthodes. Suite aux explications de M. Douin et à la relecture des diapositives du cours, j'ai compris qu'il fallait que je comprenne d'abord quel était le contrat de ces méthodes. Aucune documentation n'étant disponible, notre seule source d'information est la classe "Nombre". Comme celle-ci valide déjà explicitement les paramètres passés à ces méthodes j'en ai déduit que ces méthodes acceptaient "par contrat" n'importe quel valeur d'"int". Le type "int" ne pouvant être null et la classe elle-même ne pouvant jamais être dans un état invalide, je n'ai pas vu de précondition suffisamment intéressante à ajouter à ces méthodes.

Concernant le test "testNombrePrePost" je n'y ai pas touché. En effet, il me semble impossible sans modifier le constructeur de la classe de le faire passer. La seule modification serait de ne pas tester le paramètre passé au constructeur de "NombrePrePost" mais cela semble surprenant d'enlever un test réellement utile.

Comme tu l'as remarqué cette partie de la question n'est pas à soumettre (ou alors je n'ai pas compris comment le faire non plus), je me suis donc contenté d'expliquer cela dans mon document.

Merci et bon courage !

Re: TP8 - Question 3 : Quelques informations ?

Publié : 22 déc. 2017 11:41
par Alban_lp
Bonjour Franck

Oui, pour les "pre" à part tester "null" je ne vois pas..mais on a un int !
Pour la fameuse décoration du constructeur, j'ai poussé l'idée du test de la classe du paramètre par introspection ci-dessous :

public NombrePrePost(NombreI nombre) {
super(nombre==nombre?pre_NombrePrePost(nombre):null);
assert post_NombrePrePost(nombre):"post assertion NombrePrePost ???";
if(super.getMin() == Integer.MAX_VALUE-1 && super.getMax() == Integer.MAX_VALUE) throw new RuntimeException("Mauvais parametre du constructeur");// on rétabli l'erreur classique pour la suite
}

protected static NombreI pre_NombrePrePost(NombreI nombre){
NombreI NombreImprobable = new Nombre(Integer.MAX_VALUE-1,Integer.MAX_VALUE);
try {
Class<?> cl = nombre.getClass();//class du nombre paramètre
Class<?> clsup = Class.forName("nombre_exemple.NombreI");//interface NombreI
if(cl.getInterfaces()[0]==clsup) { //test si la class du nombre implémente interface NombreI
NombreImprobable = nombre; //on envoi le nb au constructeur sinon on envoi le nombre improbable
}
} catch(Exception e){}
return NombreImprobable;
}

protected boolean post_NombrePrePost(NombreI nombre){ //tout va bien ou alors on a le nombre improbable
return (super.getValeur() == nombre.getValeur()) || (super.getMin() == Integer.MAX_VALUE-1 && super.getMax() == Integer.MAX_VALUE);
}

Bon c'est du bricolage avec mon nombre improbable !!! L'idée c'est de créer en "pre" une instance spécial dans le cas ou le paramètre n'est pas bon puis de la testée en post, ce qui permet de travaillé sans exception dans un premier temps puis de rétablir cette exception. Ça marche en adaptant le test :

public void testNombrePrePost() {
try{
this.n = new NombrePrePost(null);
fail(" une exception est attendue ");
}catch(Exception e){
assertTrue( e instanceof RuntimeException);
}
}

Après je na sais pas du tout si cela répond vraiment à la question, qu'en penses-tu !?!
@+ Alban

Re: TP8 - Question 3 : Quelques informations ?

Publié : 22 déc. 2017 11:42
par Douin
Bonjour, ci dessous une solution aux tests de la pré-assertion avant l'appel du constructeur de la super-classe

Code : Tout sélectionner

super(nombre==nombre?pre_NombrePrePost(nombre):null);
Cela s'apparente à du bricolage en java, avec un petit tournevis...

Vivement le cours sur la variabilité du logiciel ;-)

Bonne lecture

Bonne fin de tp

Code : Tout sélectionner

public class NombrePrePost extends NombreDecorateur{
  protected boolean post_NombrePrePost(){
    return true;
  }
    
  public NombrePrePost(NombreI nombre){
    super(nombre==nombre?pre_NombrePrePost(nombre):null);
    assert post_NombrePrePost();
  }
  
  protected static NombreI pre_NombrePrePost(NombreI nombre){
    assert nombre!=null && nombre.getMax() >= nombre.getMin() : "pre assertion NombrePrePost invalide ???";
    // utile ?, une exception aurait dû être levée avant l'appel du décorateur
    return nombre;
  }
  
  

Re: TP8 - Question 3 : Quelques informations ?

Publié : 22 déc. 2017 11:43
par Alban_lp
Excuse l'orthographe...je suis un peu fatigué !!