web-dev-qa-db-fra.com

Chaque méthode doit-elle renvoyer une valeur pour les tests unitaires?

J'apprends à créer des tests unitaires simples pour éventuellement (et j'espère) commencer à ne faire que TDD; pour l'instant j'essaie d'écrire des tests pour du code déjà écrit pour voir ce qui pourrait causer des problèmes. C'est l'un d'eux.

Disons que j'ai cette classe simple (avec TypeScript-> Javascript):

class PrivateStuff {
    greeting: string;
    private _thisIsPrivate;

    constructor(isPrivate: boolean) {
        this._thisIsPrivate = isPrivate;
    }

    setPrivate(option) {
        this._thisIsPrivate = option;
        console.log("_thisIsPrivate changed to : " + option);
    }

    getPrivate() {
        console.log("_thisIsPrivate is : " + this._thisIsPrivate);
        return this._thisIsPrivate;        
    }
}

Et je l'utilise de cette façon:

let privateStuff = new PrivateStuff(false);

let buttonSet = document.createElement('button');
buttonSet.textContent = "Set True";
buttonSet.onclick = function () {
    privateStuff.setPrivate(true);
}

let buttonGet = document.createElement('button');
buttonGet.textContent = "Get";
buttonGet.onclick = function() {
    console.log(privateStuff.getPrivate());
}
document.body.appendChild(buttonSet);
document.body.appendChild(buttonGet);

setPrivate() n'a pas besoin de retourner quoi que ce soit, mais à cause de cela je ne peux pas le tester. Lors de la création d'un test unitaire pour cela, dois-je refactoriser le code?

Si je faisais TDD, devrais-je toujours créer des méthodes qui retournent quelque chose juste pour pouvoir le tester? Ou je manque quelque chose?

P.S. Vous pouvez voir et exécuter le code ici

12
distante

Je suppose que votre idée fausse ici est qu'un "sujet sous test" doit toujours être une méthode à part entière. Mais ce n'est pas vrai, bien que certaines méthodes puissent être testées sans utiliser d'autres méthodes, la taille typique d'un SUT est une classe, ou certaines méthodes et fonctions en interaction d'une classe. Donc, si vous avez une méthode qui change l'état interne d'un objet, il doit y avoir toujours une modification visible de l'extérieur du comportement de cet objet (sinon cela n'aurait aucun sens d'avoir la méthode dans le première place). Et dans un test unitaire, vous pouvez valider exactement ce comportement.

Par exemple, supposons que vous ayez une classe NumberFormatter avec la responsabilité de formater les nombres à virgule flottante d'une manière prédéfinie. Supposons qu'il contient une méthode FormatToString(double d). Supposons en outre qu'il a une méthode setDecimalSeparator, mais pas getDecimalSeparator. Néanmoins, vous pouvez facilement écrire un test si après un appel à setDecimalSeparator la méthode FormatToString se comporte de la manière souhaitée. Un tel test pourrait ressembler à ceci

  var nf = new NumberFormatter();
  nf.setDecimalSeparator(".");
  AssertEqual("12.34",nf.FormatToString(12.34))
  nf.setDecimalSeparator(",");
  AssertEqual("12,34",nf.FormatToString(12.34))

Il s'agit donc d'un test significatif de setDecimalSeparator, une méthode sans valeur de retour.

21
Doc Brown