En effet, le test correspondant à la méthode utilisant ce code passait au rouge de manière complètement aléatoire.

J’ai donc cherché l’origine de ce dysfonctionnement et après m’être tapé la tête dans les murs à plusieurs reprises, j’ai fini par comprendre.

Dans mon test unitaire, j’utilise la fonction uniqid() pour nourrir la méthode que je teste.

Comme son nom l’indique, cette fonction génère une chaîne aléatoire unique, composée de lettres et de chiffres, y compris le chiffre 0.

Or, si le résultat de l’appel à la fonction substr() est 0, la condition à gauche de l’opérateur ?: n'est pas vérifiée et ce dernier retourne donc la valeur située à sa droite.

Du coup, un caractère est perdu par mon code, ce qui fait alors passer mon test au rouge.

La solution consiste donc à recourir à une solution plus traditionnelle pour tester le retour de la fonction substr(), au prix d’un code moins condensé, à savoir $string = substr($string, $index); if ($string === false) $string = '';.

Et évidemment, il faut également ajouter dans le test unitaire le cas ou substr() retourne la chaîne 0 afin de prévenir l’éventuelle régression susceptible de survenir lorsque, dans quelque temps, j’aurais oublié la raison d’être de ce formalisme plus verbeux ou lorsqu’un tiers voudra le remplacer par l’opérateur ?: en pensant bien faire.

Et c’est également l’un des rares cas ou l’ajout d’un commentaire dans le code me semble pertinent.

Et pour finir, la façon dont j'ai découvert ce bug démontre l'intérêt de recourir à l'aléatoire via par exemple uniqid() dans les tests, car sans cela, j'aurais pu passer à côté et le découvrir bien plus tard, à un moment où il aurait été potentiellement bien plus onéreux à corriger.