En effet, si elle fonctionne pour tout ce qui est propriété publique d'une classe, elle ne prend pas du tout en compte les propriétés protégées ou privées.

De par leur nature même, ce type de propriété ne devrait pas pouvoir être modifiée par le programmeur.

Ainsi, si une méthode publique pour récupèrer la valeur d'une propriété protégée ou privée est tout à fait tolérable, une méthode publique pour modifier une telle propriété est une hérésie absolue en programmation orientée objet.

En effet, à quoi bon définir une propriété protégée ou privée si le développeur peut en faire ce qu'il veut quand il veut ?

Pourtant, il faut bien pouvoir tester les classes qui ont des propriétés de ce type.

Pour ce faire, il y a donc au moins deux solutions :

La première, que j'appelerai l'injection de dépendance statique, est de passer en argument au constructeur de la classe les objets qui devront être utilisés pour initialiser ses propriétés protégées ou privées.

L'objet est donc construit avec les objets que désire le programmeur, sans que ce dernier puisse par la suite modifier ces derniers.

L'utilisation d'une valeur par défaut pour ces arguments permet de s'affranchir des arguments dédiés aux tests dans le code de production et permet de garder un code lisible.

Le code ressemble alors à cela :

class myClass
{
private $db = null;
public $public = '';

public function __construct($public, db $db = null)
{
$this->public = $public;

if ($db === null)
{
$db = new defaultDb();
}

$this->db = $db;
}
}

Le code est alors complétement testable, sans aucune méthode permettant de définir ou modifier les propriétés privée ou protégées de la classe.

Il suffit d'appeler dans les tests le constructeur de l'objet avec une instance de la classe de son choix pour définir db :

class testMyClass extends test
{
public function test__construct()
{
...
$myClass = new myClass(uniqid(), new testDb());
...
}
}

La seconde solution, plus lourde et que je n'utilise pas, consiste à utiliser l'injection de dépendance dynamique, telle que celle présentée par Fabien Potencier.

Il est alors possible d'injecter les objets de son choix dans les propriétés protégées ou privées d'une classe sans passer par des arguments dédiés aux tests.

Le code est donc plus "propre", mais il est plus lourd et plus gourmand en ressource.

En effet, comme d'habitude, ce que le développeur gagne en facilité de codage, la machine le perd en performance.

Et pour le coup, même si je suis convaincu que la machine doit travailler au maximum pour l'humain et non le contraire, je trouve que la surchage demandée par ce type de traitement par rapport au confort gagné par le programmeur ne vaut pas le coup.

Mais cela, est une autre histoire qui n'est pas l'objet de ce billet.

En effet, la formule d'Olivier ne prend pas en compte ces techniques qui ne reposent pas sur des accesseurs ou des modificateurs déclarés explicitement par le programmeur, mais sur des méthodes "magiques" et implicites, invisible au niveau de l'interface publique de la classe.

Il n'en reste cependant pas moins que sa formule, même imparfaite, est une bonne approche pour mesurer la testabilité d'un code et qu'il serait intéressant de trouver un moyen pour qu'elle prenne en compte l'injection de dépendance, statique ou dynamique, au niveau des membres protégés et privés d'une classe.