# Constructor property promotion : ce qu’il change dans vos classes de test

> PHP 8.0 permet de déclarer et d'assigner une propriété directement dans la signature du constructeur. Pour des builders de test, l'effet est immédiat.

- Auteur : WordPress Développement
- Publié le : 2021-04-22
- Mis à jour le : 2021-04-22
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/constructor-property-promotion-classes-test/

## L’essentiel

- Déclaration et assignation en une seule ligne par propriété
- Idéal pour les builders de test et objets de valeur
- Un constructeur trois fois plus court en moyenne

`public function __construct( private string $titre, private int $auteur_id, private bool $publie = false ) {}` : cette seule ligne, en PHP 8.0, remplace ce qui nécessitait auparavant la déclaration de trois propriétés, puis leur assignation une par une dans le corps du constructeur. Pour une classe de test qui construit des objets de valeur ou des builders à répétition, ce raccourci change directement la longueur et la lisibilité du code.

La promotion des propriétés du constructeur ne modifie aucun comportement à l'exécution : elle fusionne simplement deux étapes auparavant séparées, la déclaration de la propriété et son assignation, en une seule écriture au niveau du paramètre. Ce gain, purement syntaxique, se révèle particulièrement utile sur les classes construites pour la préparation de tests.

## Avant PHP 8.0 : déclaration et assignation séparées

```
class ArticleBuilder {
    private string $titre;
    private int $auteur_id;
    private bool $publie;

    public function __construct( string $titre, int $auteur_id, bool $publie = false ) {
        $this->titre = $titre;
        $this->auteur_id = $auteur_id;
        $this->publie = $publie;
    }
}
```

Sept lignes pour trois propriétés, dont la logique se résume strictement à « prendre ce paramètre et le stocker tel quel ». Cette répétition, multipliée par le nombre de classes de builders d'un projet de tests, représente un volume de code purement mécanique qui n'apporte aucune information supplémentaire à la lecture.

## Avec la promotion de propriétés

> L'essentiel à retenir : Déclaration et assignation en une seule ligne par propriété ; Idéal pour les builders de test et objets de valeur ; Un constructeur trois fois plus court en moyenne

```
class ArticleBuilder {
    public function __construct(
        private string $titre,
        private int $auteur_id,
        private bool $publie = false
    ) {}
}
```

Le corps du constructeur est désormais vide, puisque la déclaration de la visibilité devant chaque paramètre suffit à créer la propriété et à lui assigner automatiquement la valeur reçue. Le résultat, à l'exécution, est rigoureusement identique à la version précédente.

## Un builder complet, avant et après

```
class ArticleBuilder {
    public function __construct(
        private string $titre = 'Article de test',
        private int $auteur_id = 1,
        private bool $publie = false,
        private array $categories = []
    ) {}

    public function avecTitre( string $titre ): self {
        $clone = clone $this;
        $clone->titre = $titre;
        return $clone;
    }

    public function publie(): self {
        $clone = clone $this;
        $clone->publie = true;
        return $clone;
    }

    public function construire(): int {
        return wp_insert_post( [
            'post_title'  => $this->titre,
            'post_author' => $this->auteur_id,
            'post_status' => $this->publie ? 'publish' : 'draft',
        ] );
    }
}
```

Utilisé dans un test, ce builder produit un enchaînement lisible : `(new ArticleBuilder())->avecTitre('Guide PHPUnit')->publie()->construire()`. La promotion des propriétés du constructeur n'intervient que dans la définition de la classe, mais c'est justement là que la répétition mécanique était la plus visible avant PHP 8.0.

## Une limite volontaire : pas de logique dans la promotion

La promotion assigne la valeur reçue telle quelle, sans transformation possible directement dans la signature. Si une propriété doit être normalisée avant stockage, par exemple un slug qu'il faudrait mettre en minuscules, cette logique doit rester dans le corps du constructeur, ce qui empêche alors de promouvoir cette propriété précise :

```
class ArticleBuilder {
    private string $slug;

    public function __construct(
        private string $titre,
        string $slug
    ) {
        $this->slug = sanitize_title( $slug );
    }
}
```

Ici, `$titre` reste promu directement, tandis que `$slug` nécessite un traitement avant assignation et redevient une propriété classique. Les deux styles cohabitent naturellement dans une même classe, selon que chaque propriété a besoin ou non d'une transformation à la construction.

> La promotion des propriétés du constructeur ne dispense jamais de réfléchir à ce qu'une classe de test doit réellement valider à la construction : elle raccourcit uniquement le code qui n'avait aucune logique à exprimer.

## Effet sur la lisibilité des diffs de code

Un avantage moins souvent mentionné concerne la revue de code : ajouter une nouvelle propriété promue modifie une seule ligne dans la signature du constructeur, contre trois lignes dispersées à des endroits différents de la classe auparavant. Pour une équipe qui fait évoluer fréquemment ses builders de test au fil des nouveaux besoins, ce détail réduit le bruit visuel d'une revue de code et concentre l'attention sur ce qui change réellement.

## En résumé

La promotion des propriétés du constructeur, introduite en PHP 8.0, ne change aucun comportement à l'exécution mais réduit fortement la taille du code purement mécanique dans les classes de test comme les builders et les objets de valeur. Elle se combine naturellement avec le typage de propriétés déjà disponible depuis PHP 7.4, pour des classes de fixtures à la fois plus courtes et plus sûres.
