{"id":230387,"date":"2022-11-28T16:03:00","date_gmt":"2022-11-28T13:03:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230387"},"modified":"2022-11-09T22:09:23","modified_gmt":"2022-11-09T19:09:23","slug":"une-introduction-a-la-reflexion-en-php-et-comment-cela-joue-dans-les-tests-unitaires","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/une-introduction-a-la-reflexion-en-php-et-comment-cela-joue-dans-les-tests-unitaires\/","title":{"rendered":"Une introduction \u00e0 la r\u00e9flexion en PHP (et comment cela joue dans les tests unitaires)"},"content":{"rendered":"\n<p>Au cours des derni\u00e8res semaines, j&rsquo;ai \u00e9crit sur <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">les tests unitaires<\/a><\/strong> pour les <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">membres<\/a><\/strong> du site (et quelque chose que je pr\u00e9vois de continuer \u00e0 faire dans le prochain article). C&rsquo;est quelque chose que je pense; si vous \u00e9crivez du code c\u00f4t\u00e9 serveur, vous devriez le faire.<\/p>\n<p>Bien s\u00fbr, c&rsquo;est plus facile pour moi de le dire que de le faire, donc m\u00eame si j&rsquo;essaie de faire du bon travail, il y a toujours de la place pour que je m&rsquo;am\u00e9liore. Je dis cela plus comme une v\u00e9rification personnelle qu&rsquo;autre chose, alors je m&rsquo;\u00e9loigne du sujet.<\/p>\n<p>L&rsquo;un des concepts qui revient souvent lors des tests est l&rsquo;id\u00e9e de tester les valeurs des attributs priv\u00e9s. Par exemple, disons que vous avez un setter, mais vous n&rsquo;avez pas n\u00e9cessairement un getter pour cette valeur particuli\u00e8re.<\/p>\n<p>Il est facile de dire &quot;Eh bien, alors vous devez \u00e9crire un getter&quot;, mais ce n&rsquo;est pas toujours le cas. Je veux dire, que se passe-t-il si vous stockez des informations dans la classe qui n&rsquo;ont pas besoin d&rsquo;\u00eatre expos\u00e9es \u00e0 des classes tierces ?<\/p>\n<p>Comment alors sommes-nous cens\u00e9s \u00e9crire des tests sur ce type de donn\u00e9es lorsque nous voulons y acc\u00e9der mais que nous n&rsquo;en avons pas la capacit\u00e9 et que nous ne voulons pas compromettre l&rsquo;int\u00e9grit\u00e9 de notre travail\u00a0?<\/p>\n<p>C&rsquo;est l\u00e0 que la r\u00e9flexion entre en jeu.<\/p>\n<h2>R\u00e9flexion en PHP<\/h2>\n<p>Plus pr\u00e9cis\u00e9ment, pour comprendre comment inspecter la valeur d&rsquo;une variable donn\u00e9e de l&rsquo;ext\u00e9rieur vers l&rsquo;int\u00e9rieur, il faut savoir utiliser la r\u00e9flexion.<\/p>\n<p>Heureusement, PHP nous fournit une API puissante pour le faire, et cela vaut probablement la peine d&rsquo;entrer dans les d\u00e9tails dans un autre article. Mais, pour celui-ci, s&rsquo;en tenir \u00e0 l&rsquo;essentiel.<\/p>\n<h3>Une d\u00e9finition de travail<\/h3>\n<p>Tout d&rsquo;abord, un regard sur ce que signifie la r\u00e9flexion. Le manuel PHP le <strong><a href=\"https:\/\/php.net\/manual\/en\/class.reflectionclass.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">d\u00e9finit ainsi<\/a><\/strong> :<\/p>\n<blockquote>\n<p>La classe <strong>ReflectionClass<\/strong> rapporte des informations sur une classe.<\/p>\n<\/blockquote>\n<p>Mais je pense que \u00e7a vaut la peine d&rsquo;avoir quelque chose d&rsquo;un peu plus solide. Allons-y avec quelque chose comme \u00e7a au moins pour ce post:<\/p>\n<blockquote>\n<p>La r\u00e9flexion est la fa\u00e7on dont un programme s&rsquo;inspecte et se modifie pendant l&rsquo;ex\u00e9cution.<\/p>\n<\/blockquote>\n<p>Ce n&rsquo;est peut-\u00eatre pas g\u00e9nial; peut \u00eatre pas.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164036-61e75c7d26d26.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164036-61e75c7d26d26.png\" alt=\"Une introduction \u00e0 la r\u00e9flexion en PHP (et comment cela joue dans les tests unitaires)\" ><\/a><\/p>\n<p>Mais cela servira l&rsquo;objectif de ce post.<\/p>\n<h3>Lire une valeur par r\u00e9flexion<\/h3>\n<p>Supposons que pour cet article, vous ayez une classe d&rsquo;espaces de noms sur <strong>AcmePluginAPIClient<\/strong> et qu&rsquo;elle ait une propri\u00e9t\u00e9 appel\u00e9e <strong>username<\/strong>. Nous verrons plus tard \u00e0 quoi pourrait ressembler une impl\u00e9mentation tr\u00e8s basique de ceci.<\/p>\n<p>Bien s\u00fbr, ce serait beaucoup plus \u00e9toff\u00e9 dans un plugin r\u00e9el.<\/p>\n<p>Supposons cependant que vous souhaitiez d\u00e9finir la valeur de l&rsquo;attribut, puis lire sa valeur. La mise en garde est que la propri\u00e9t\u00e9 est marqu\u00e9e comme <strong>priv\u00e9e<\/strong> et qu&rsquo;il n&rsquo;y a aucun moyen de la lire de l&rsquo;ext\u00e9rieur.<\/p>\n<p>C&rsquo;est l\u00e0 que la r\u00e9flexion devient utile. Autrement dit, nous pouvons utiliser une partie du programme pour se regarder et rendre compte de ce qu&rsquo;il voit. (R\u00e9flexion, compris\u00a0? C&rsquo;est comme quand nous voulons savoir ce qui se passe avec nous-m\u00eames et que personne d&rsquo;autre n&rsquo;est l\u00e0, alors nous nous regardons dans un miroir et voyons ce qu&rsquo;il y a.)<\/p>\n<p>Pour ce faire, vous devez faire cinq choses :<\/p>\n<ol>\n<li>Instanciez la classe que vous souhaitez tester,<\/li>\n<li>D\u00e9finissez la valeur de la variable,<\/li>\n<li>Prenez une instance de <strong>ReflectionClass<\/strong> pour la classe que nous voulons tester,<\/li>\n<li>D\u00e9finissez sa propri\u00e9t\u00e9 sur accessible,<\/li>\n<li>Lisez la valeur.<\/li>\n<\/ol>\n<p>Voici donc une s\u00e9rie d&rsquo;essentiels qui fourniront les \u00e9tapes n\u00e9cessaires pour faire exactement cela.<\/p>\n<h4>1 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/c835d263062e768980d5ad3f6941f60e#file-00-apiclient-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Instancier la classe<\/a><\/h4>\n<pre><code>&lt;?php\n\nnamespace AcmePlugin;\n\nclass APIClient\n{\n  private $username;\n\n  \/\/ Other functions for class implementation...\n}\n<\/code><\/pre>\n<h4>2 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/c835d263062e768980d5ad3f6941f60e#file-01-setusername-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">D\u00e9finissez la valeur<\/a><\/h4>\n<pre><code>&lt;?php\n\nnamespace AcmePlugin;\n\nclass APIClient\n{\n  private $username;\n\n  public function setUsername($username)\n  {\n    $this-&gt;username = $username;\n  }\n\n  \/\/ Other functions for class implementation...\n}\n<\/code><\/pre>\n<h4>3 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/c835d263062e768980d5ad3f6941f60e#file-01-apiclienttest-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Instancier les objets r\u00e9fl\u00e9chis<\/a><\/h4>\n<pre><code>&lt;?php\n\nnamespace AcmePluginTests;\n\nuse AcmePluginAPIAPIClient;\n\nclass APIClientTest\n{\n  public function setUsername()\n  {\n\n    \/\/ Instantiate the class.\n    $client = new APIClient();\n    $username = 'tommcfarlin';\n    $client-&gt;setUsername($username);\n\n    \/\/ Now get a reflected instance of the class.\n    $reflectedClient = new ReflectionClass('AcmePluginAPIAPIClient');\n\n    \/\/ More to come...\n  }\n}\n<\/code><\/pre>\n<h4>4. <a href=\"https:\/\/gist.github.com\/tommcfarlin\/c835d263062e768980d5ad3f6941f60e#file-02-setaccessibleproperty-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">D\u00e9finissez la propri\u00e9t\u00e9, marquez-la comme accessible<\/a><\/h4>\n<pre><code>&lt;?php\n\nnamespace AcmePluginTests;\n\nuse AcmePluginAPIAPIClient;\n\nclass APIClientTest\n{\n  public function setUsername()\n  {\n\n    \/\/ Instantiate the class.\n    $client = new APIClient();\n    $username = 'tommcfarlin';\n    $client-&gt;setUsername($username);\n\n    \/\/ Now get a reflected instance of the class.\n    $reflectedClient = new ReflectionClass('AcmePluginAPIAPIClient');\n    $usernameProperty = new ReflectionObject($client);\n    $usernameProperty-&gt;setAccessible(true);\n\n    \/\/ More to come...\n  }\n}\n<\/code><\/pre>\n<h4>5 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/c835d263062e768980d5ad3f6941f60e#file-03-readpropertyvalue-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Lisez la valeur<\/a><\/h4>\n<pre><code>&lt;?php\n\nnamespace AcmePluginTests;\n\nuse AcmePluginAPIAPIClient;\n\nclass APIClientTest\n{\n  public function setUsername()\n  {\n\n    \/\/ Instantiate the class.\n    $client = new APIClient();\n    $username = 'tommcfarlin';\n    $client-&gt;setUsername($username);\n\n    \/\/ Now get a reflected instance of the class.\n    $reflectedClient = new ReflectionClass('AcmePluginAPIAPIClient');\n\n    \/\/ Grab a reference to the private property by making it accessible.\n    $usernameProperty = new ReflectionObject($client);\n    $usernameProperty-&gt;setAccessible(true);\n\n    \/\/ And finally, read it's value.\n    $usernameValue = $usernameProperty-&gt;getValue($client);\n  }\n}\n<\/code><\/pre>\n<h2>Et c&rsquo;est l&rsquo;amorce de base sur la r\u00e9flexion<\/h2>\n<p>\u00c0 ce stade, cela devrait vous donner quelques informations de base sur ce qu&rsquo;est Reflection, comment l&rsquo;utiliser et pourquoi il est utile, en particulier dans le cas des <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tests unitaires<\/a><\/strong>.<\/p>\n<p>C&rsquo;est l&rsquo;un de ces concepts qui peuvent devenir plus complexes car l&rsquo;API de r\u00e9flexion de PHP est assez puissante (mais relativement facile \u00e0 comprendre). Cependant, lorsque vous le couplez avec des tests unitaires, il y a beaucoup de choses qui peuvent \u00eatre faites.<\/p>\n<h3>Ma prise sans vergogne<\/h3>\n<p>Cela dit, si vous souhaitez apprendre les tenants et les aboutissants de ce genre de choses, n&rsquo;h\u00e9sitez pas \u00e0 consulter la zone <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">r\u00e9serv\u00e9e aux membres<\/a><\/strong> du site. Je construis, chaque semaine, <strong><a href=\"https:\/\/tommcfarlin.com\/members-only-content\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">un carnet de commandes<\/a><\/strong> pour nous aider \u00e0 nous concentrer sur l&rsquo;adoption de meilleures pratiques en tant que d\u00e9veloppeurs WordPress.<\/p>\n<p>Les tests unitaires, la r\u00e9flexion et plus encore ne sont que la derni\u00e8re partie de celui-ci.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Comprendre les bases de la r\u00e9flexion en PHP peut aider \u00e0 rendre votre programmation, en particulier les tests, beaucoup plus facile.<\/p>\n","protected":false},"author":1,"featured_media":164037,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,717,801],"tags":[1167],"class_list":["post-230387","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-2","category-developpeur","category-php-3","tag-affiai-fr"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/230387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/comments?post=230387"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/230387\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/164037"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=230387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=230387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=230387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}