Unpopular : si vous complexifiez votre code pour le rendre testable, you are doing it wrong.

Prenons un use case : SignUp

La post-condition qu'on veut c'est :

👉 L'utilisateur peut s'authentifier
👉 👉 Donc son compte utilisateur existe en DB [1]
👉 Un email de bienvenue lui a été envoyé
👉 Il est inscrit à la newsletter s'il y consent

Le code associé, pour être compréhensible donc maintenable, devrait ressembler à ceci :

class SignUp

  [...]
  
  def run
    create_user_account
    send_welcome_email
    if newsletter_consent?
      subscribe_to_newsletter
    end
  end

  [...]

end

Et il n'y a que deux tests fonctionnels à écrire, parce qu'il n'y a qu'une seule condition.

Si vous avez introduit un bus, des événements, des ports, des adapters et plein d'injection de services pour rendre votre code testable unitairement, grand bien vous fasse.

Il y a de grandes chances que vous ayez :

👉 rendu le code impigeable pour les suivants
👉 complexifié en introduisant des abstractions accidentelles
👉 écrit des tests rapides certes, mais qui passent trivialement
👉 déplacé la découverte de bugs vers la prod

Perso, je défends :

💡 qu’un use case n'est PAS testable en unitaire, par nature.
💡que la complexité est mieux placée dans l’infra de tests que dans la logique business.
💡qu’il faut plutôt investir dans des tests d'intégration et une CI convenables

#SoftwareEngineering


  1. dire "the database is a detail" c’est soutenir que la postcondition "l'utilisateur peut s'authentifier après s'être inscrit" n'a pas d'importance. En effet, c’est nier la POST-condition la plus importante du use case. ↩︎

Retour