{"id":230514,"date":"2022-11-28T16:28:00","date_gmt":"2022-11-28T13:28:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230514"},"modified":"2022-11-09T22:44:33","modified_gmt":"2022-11-09T19:44:33","slug":"uma-cartilha-sobre-reflexao-em-php-e-como-isso-funciona-no-teste-de-unidade","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/uma-cartilha-sobre-reflexao-em-php-e-como-isso-funciona-no-teste-de-unidade\/","title":{"rendered":"Uma cartilha sobre reflex\u00e3o em PHP (e como isso funciona no teste de unidade)"},"content":{"rendered":"\n<p>Nas \u00faltimas semanas, tenho escrito sobre <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">testes unit\u00e1rios<\/a><\/strong> para os <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">membros<\/a><\/strong> do site (e algo que pretendo continuar fazendo no pr\u00f3ximo post). \u00c9 algo que eu acho; se voc\u00ea escrever c\u00f3digo do lado do servidor, voc\u00ea deve estar fazendo.<\/p>\n<p>Claro, \u00e9 mais f\u00e1cil para mim dizer do que faz\u00ea-lo, ent\u00e3o, embora eu tente fazer um bom trabalho, sempre h\u00e1 espa\u00e7o para melhorar. Eu digo isso mais como uma verifica\u00e7\u00e3o pessoal do que qualquer outra coisa, ent\u00e3o eu discordo.<\/p>\n<p>Um dos conceitos que surgem frequentemente durante os testes \u00e9 a ideia de testar os valores dos atributos privados. Por exemplo, digamos que voc\u00ea tenha um setter, mas n\u00e3o necessariamente um getter para esse valor espec\u00edfico.<\/p>\n<p>\u00c9 f\u00e1cil dizer &quot;Bem, ent\u00e3o voc\u00ea precisa escrever um getter&quot;, mas nem sempre \u00e9 esse o caso. E se voc\u00ea estiver armazenando algumas informa\u00e7\u00f5es dentro da classe que n\u00e3o precisam ser expostas a classes de terceiros?<\/p>\n<p>Como ent\u00e3o devemos escrever testes contra esse tipo de dados quando queremos acess\u00e1-los, mas n\u00e3o temos a capacidade de faz\u00ea-lo e n\u00e3o queremos comprometer a integridade do nosso trabalho?<\/p>\n<p>\u00c9 a\u00ed que entra a reflex\u00e3o.<\/p>\n<h2>Reflex\u00e3o em PHP<\/h2>\n<p>Especificamente, para entender como inspecionar o valor de uma determinada vari\u00e1vel de fora para dentro, voc\u00ea precisa saber como usar a reflex\u00e3o.<\/p>\n<p>Felizmente, o PHP nos fornece uma API poderosa para fazer isso, e provavelmente vale a pena entrar nos detalhes profundos disso em outro post. Mas, para este, vai ficar com o b\u00e1sico.<\/p>\n<h3>Uma defini\u00e7\u00e3o de trabalho<\/h3>\n<p>Primeiro, uma olhada no que significa reflex\u00e3o. O manual do PHP <strong><a href=\"https:\/\/php.net\/manual\/en\/class.reflectionclass.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">define como<\/a><\/strong> :<\/p>\n<blockquote>\n<p>A classe <strong>ReflectionClass<\/strong> relata informa\u00e7\u00f5es sobre uma classe.<\/p>\n<\/blockquote>\n<p>Mas acho que vale a pena ter algo um pouco mais s\u00f3lido. Vamos com algo assim pelo menos para este post:<\/p>\n<blockquote>\n<p>Reflex\u00e3o \u00e9 como um programa se inspeciona e se modifica durante o tempo de execu\u00e7\u00e3o.<\/p>\n<\/blockquote>\n<p>Talvez n\u00e3o seja \u00f3timo; talvez n\u00e3o.<\/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=\"Uma cartilha sobre reflex\u00e3o em PHP (e como isso funciona no teste de unidade)\" ><\/a><\/p>\n<p>Mas servir\u00e1 ao prop\u00f3sito deste post.<\/p>\n<h3>Lendo um valor por meio de reflex\u00e3o<\/h3>\n<p>Vamos supor que para este post, voc\u00ea tenha uma classe de namespaces em <strong>AcmePluginAPIClient<\/strong> e tenha uma propriedade chamada <strong>username<\/strong>. Vamos dar uma olhada em como pode ser uma implementa\u00e7\u00e3o muito b\u00e1sica disso mais tarde.<\/p>\n<p>Claro, seria muito mais desenvolvido em um plugin real.<\/p>\n<p>Digamos, no entanto, que voc\u00ea deseja definir o valor do atributo e, em seguida, ler seu valor. A ressalva \u00e9 que a propriedade est\u00e1 marcada como <strong>privada<\/strong> e n\u00e3o h\u00e1 como l\u00ea-la de fora.<\/p>\n<p>\u00c9 aqui que a reflex\u00e3o vem a calhar. Ou seja, podemos usar uma parte do programa para olhar para si mesmo e relatar o que v\u00ea. (Reflex\u00e3o, entendeu? \u00c9 como quando queremos saber o que est\u00e1 acontecendo conosco e ningu\u00e9m mais est\u00e1 por perto, ent\u00e3o olhamos no espelho e vemos o que est\u00e1 l\u00e1.)<\/p>\n<p>Para fazer isso, voc\u00ea precisa fazer cinco coisas:<\/p>\n<ol>\n<li>Instancie a classe que deseja testar,<\/li>\n<li>Defina o valor da vari\u00e1vel,<\/li>\n<li>Pegue uma inst\u00e2ncia do <strong>ReflectionClass<\/strong> para a classe que queremos testar,<\/li>\n<li>Defina sua propriedade como acess\u00edvel,<\/li>\n<li>Leia o valor.<\/li>\n<\/ol>\n<p>Ent\u00e3o, aqui est\u00e1 uma s\u00e9rie de ess\u00eancias que fornecer\u00e3o as etapas necess\u00e1rias para fazer exatamente isso.<\/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\">Instanciar a 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\">Defina o valor<\/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\">Instanciar Objetos Refletidos<\/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\">Defina a propriedade, marque-a como acess\u00edvel<\/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\">Leia o valor<\/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>E essa \u00e9 a cartilha b\u00e1sica sobre reflex\u00e3o<\/h2>\n<p>Neste ponto, isso deve fornecer algumas informa\u00e7\u00f5es b\u00e1sicas sobre o que \u00e9 o Reflection, como us\u00e1-lo e por que ele \u00e9 \u00fatil, especialmente no caso de <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">testes de unidade<\/a><\/strong>.<\/p>\n<p>Este \u00e9 um daqueles conceitos que podem ficar mais complexos porque a API de reflex\u00e3o do PHP \u00e9 bastante poderosa (mas relativamente f\u00e1cil de entender). No entanto, quando voc\u00ea combina com testes de unidade, h\u00e1 muitas coisas que podem ser feitas.<\/p>\n<h3>Meu plugue sem vergonha<\/h3>\n<p>Com isso dito, se voc\u00ea estiver interessado em aprender os pr\u00f3s e contras desse tipo de coisa, n\u00e3o hesite em conferir a \u00e1rea <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">exclusiva para membros<\/a><\/strong> do site. Estou construindo, a cada semana, <strong><a href=\"https:\/\/tommcfarlin.com\/members-only-content\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">uma lista de pend\u00eancias<\/a><\/strong> para nos ajudar a nos concentrar em adotar as melhores pr\u00e1ticas como desenvolvedores do WordPress.<\/p>\n<p>Teste de unidade, reflex\u00e3o e muito mais \u00e9 apenas a parte mais recente.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Compreender os conceitos b\u00e1sicos de reflex\u00e3o em PHP pode ajudar a tornar sua programa\u00e7\u00e3o, especialmente testes, muito mais f\u00e1cil.<\/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":[898,722,806],"tags":[1170],"class_list":["post-230514","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-php-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=230514"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230514\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/164037"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}