web-dev-qa-db-fra.com

Comment tester correctement une méthode appelée par un hook d’action

Le constructeur de ma classe ajoute une action au hook d’action 'init':

class My_Custom_Post_Type {

    function __construct( $type ) {
        $this->type = $type;
        add_action( 'init', array( $this, 'register_my_type' );
    }

    function register_my_type() {
        register_post_type( $this->type);
    } 
}    

J'essayais de tester cela dans un test unitaire et j'ai finalement réalisé qu'il n'y avait aucune raison pour que le crochet d'action 'init' se déclenche. Existe-t-il un moyen de vérifier que la méthode register_my_type est appelée et qu'un nouveau type de publication est en cours d'enregistrement?

Modifier:

La principale source de ma confusion provient de la non-compréhension de la relation entre phpunit, la suite de tests WordPress, mon code de classe et mon code de test.

Ce que je comprends maintenant, c’est que, avec les outils de développement WordPress installés de la manière suggérée par ce tutoriel ou par le biais de WP-CLI , un appel à phpunit charge un fichier d’amorçage qui raccorde ensuite le plug-in au. muplugins_loaded crochet d'action. Le fichier d'amorçage charge ensuite l'environnement de test WordPress. Une fois que WordPress a fini de charger, le hook init est exécuté. Le code de plugin qui utilise init devrait fonctionner comme prévu.

Les tests sont principalement du code normal qui utilise les fonctions ou les classes disponibles. Leur différence est qu’elles sont écrites comme les méthodes d’une classe qui étend WP_UnitTestCase qui étend PHPUnit_Framework_TestCase. Le fait d'être encapsulé dans cette classe donne aux tests l'accès aux assertions et aux fabriques d'objets, et exécute les méthodes setUp et tearDown de sorte que chaque test soit indépendant des autres.

2
Simon Cossar

Permettez-moi de commencer en disant que l'action initestappelée lorsque WordPress est chargé, avant l'exécution des tests. Ainsi, si votre plugin/thème est chargé avec WordPress (en vous connectant à muplugins_loaded, par exemple), la méthode register_my_type() devrait être appelée, si votre constructeur est appelé avant init. (Si vous ne chargez pas votre plugin de cette façon, regardez ce tutoriel .)

Donc, dans vos tests unitaires, vous devriez pouvoir faire ceci:

$this->assertTrue( post_type_exists( 'my_post_type' ) );

Vous pouvez également utiliser get_post_type() pour vérifier que le type de publication a été enregistré avec les arguments corrects. (C’est la même chose que je fais pour vérifier que mes codes courts sont bien enregistrés.)

Je ne voudrais pas essayer de vérifier que la méthode a été appelée, bien que vous puissiez vérifier la liste des actions dans $wp_actions pour voir si elle était correctement connectée. Vous pouvez également définir une propriété de classe comme un indicateur lorsqu'elle est appelée, mais je pense vraiment que tout cela est excessif. Quand il s’agit de choses liées à des actions comme init, en particulier d’une fonction comme celle-ci, qui ne doit être exécutée qu’une seule fois, les tests fonctionnels sont votre meilleur choix. Vérifiez qu'ils ont bien fait ce qu'ils sont supposés faire, plutôt que d'essayer de tester une seule unité, comme si la méthode était appelée.

Cela dit, vous pouvez également vérifier que la méthode enregistre le type de publication en désenregistrant le type de publication et en appelant manuellement la méthode. WordPress ne semble pas fournir une fonction deregister_post_type(), vous devez donc vous occuper directement du $wp_post_types global. Vous pouvez supprimer votre type de publication, puis appeler votre méthode et vérifier si elle est à nouveau enregistrée.

1
J.D.