{"id":229807,"date":"2022-11-28T16:38:00","date_gmt":"2022-11-28T13:38:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229807"},"modified":"2022-11-09T16:27:59","modified_gmt":"2022-11-09T13:27:59","slug":"elementarz-do-refleksji-w-php-i-jak-to-sie-sprawdza-w-testach-jednostkowych","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/elementarz-do-refleksji-w-php-i-jak-to-sie-sprawdza-w-testach-jednostkowych\/","title":{"rendered":"Elementarz do refleksji w PHP (i jak to si\u0119 sprawdza w testach jednostkowych)"},"content":{"rendered":"\n<p>Od kilku tygodni pisz\u0119 o <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">testach jednostkowych<\/a><\/strong> dla <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">cz\u0142onk\u00f3w<\/a><\/strong> serwisu (i co\u015b, co planuj\u0119 kontynuowa\u0107 w nast\u0119pnym po\u015bcie). To jest co\u015b, o czym my\u015bl\u0119; je\u015bli piszesz kod po stronie serwera, powiniene\u015b to robi\u0107.<\/p>\n<p>Oczywi\u015bcie \u0142atwiej mi to powiedzie\u0107, ni\u017c zrobi\u0107, wi\u0119c chocia\u017c staram si\u0119, aby dobrze to robi\u0142em, zawsze jest miejsce na popraw\u0119. M\u00f3wi\u0119 to bardziej jako osobista intuicja ni\u017c cokolwiek innego, wi\u0119c robi\u0119 dygresj\u0119.<\/p>\n<p>Jedn\u0105 z koncepcji, kt\u00f3ra cz\u0119sto pojawia si\u0119 podczas testowania, jest idea testowania warto\u015bci atrybut\u00f3w prywatnych. Za\u0142\u00f3\u017cmy na przyk\u0142ad, \u017ce masz setter, ale niekoniecznie masz getter dla tej konkretnej warto\u015bci.<\/p>\n<p>\u0141atwo jest powiedzie\u0107 \u201eC\u00f3\u017c, w takim razie musisz napisa\u0107 getter&quot;, ale nie zawsze tak jest. Mam na my\u015bli to, \u017ce przechowujesz pewne informacje w klasie, kt\u00f3re nie musz\u0105 by\u0107 udost\u0119pniane klasom firm trzecich?<\/p>\n<p>Jak wi\u0119c mamy pisa\u0107 testy na tego rodzaju danych, kiedy chcemy uzyska\u0107 do nich dost\u0119p, ale nie mamy do tego mo\u017cliwo\u015bci i nie chcemy narusza\u0107 integralno\u015bci naszej pracy?<\/p>\n<p>I tu pojawia si\u0119 refleksja.<\/p>\n<h2>Refleksja w PHP<\/h2>\n<p>W szczeg\u00f3lno\u015bci, aby zrozumie\u0107, jak sprawdzi\u0107 warto\u015b\u0107 danej zmiennej z zewn\u0105trz, trzeba wiedzie\u0107, jak korzysta\u0107 z odbicia.<\/p>\n<p>Na szcz\u0119\u015bcie PHP dostarcza nam do tego pot\u0119\u017cne API i prawdopodobnie warto zag\u0142\u0119bi\u0107 si\u0119 w szczeg\u00f3\u0142y w innym po\u015bcie. Ale w tym przypadku pozostanie przy podstawach.<\/p>\n<h3>Robocza definicja<\/h3>\n<p>Najpierw sp\u00f3jrz na to, co oznacza odbicie. Podr\u0119cznik PHP <strong><a href=\"https:\/\/php.net\/manual\/en\/class.reflectionclass.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">definiuje to jako<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Klasa <strong>ReflectionClass<\/strong> raportuje informacje o klasie.<\/p>\n<\/blockquote>\n<p>Ale my\u015bl\u0119, \u017ce warto mie\u0107 co\u015b bardziej solidnego. Przejd\u017amy z czym\u015b takim przynajmniej do tego postu:<\/p>\n<blockquote>\n<p>Refleksja to spos\u00f3b, w jaki program sprawdza si\u0119 i modyfikuje w czasie wykonywania.<\/p>\n<\/blockquote>\n<p>Mo\u017ce to nie jest \u015bwietne; mo\u017ce nie.<\/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=\"Elementarz do refleksji w PHP (i jak to si\u0119 sprawdza w testach jednostkowych)\" ><\/a><\/p>\n<p>Ale to b\u0119dzie s\u0142u\u017cy\u0107 temu po\u015bcie.<\/p>\n<h3>Odczytywanie warto\u015bci poprzez refleksj\u0119<\/h3>\n<p>Za\u0142\u00f3\u017cmy, \u017ce w tym po\u015bcie masz klas\u0119 przestrzeni nazw w <strong>AcmePluginAPIClient<\/strong> i posiada ona w\u0142a\u015bciwo\u015b\u0107 nazwan\u0105 <strong>username<\/strong>. P\u00f3\u017aniej przyjrzymy si\u0119, jak bardzo podstawowa implementacja tego mo\u017ce wygl\u0105da\u0107.<\/p>\n<p>Oczywi\u015bcie by\u0142oby to znacznie bardziej rozbudowane w rzeczywistej wtyczce.<\/p>\n<p>Powiedzmy jednak, \u017ce chcesz ustawi\u0107 warto\u015b\u0107 atrybutu, a nast\u0119pnie odczyta\u0107 jego warto\u015b\u0107. Zastrze\u017cenie polega na tym, \u017ce nieruchomo\u015b\u0107 jest oznaczona jako <strong>prywatna<\/strong> i nie ma mo\u017cliwo\u015bci odczytania jej z zewn\u0105trz.<\/p>\n<p>Tutaj przydaje si\u0119 refleksja. Oznacza to, \u017ce mo\u017cemy u\u017cy\u0107 cz\u0119\u015bci programu, aby spojrze\u0107 na siebie i zg\u0142osi\u0107 to, co widzi. (Odbicie, rozumiesz? To tak, jakby\u015bmy chcieli wiedzie\u0107, co si\u0119 dzieje z nami i nikogo innego nie ma w pobli\u017cu, wi\u0119c patrzymy w lustro i widzimy, co tam jest.)<\/p>\n<p>Aby to zrobi\u0107, musisz zrobi\u0107 pi\u0119\u0107 rzeczy:<\/p>\n<ol>\n<li>Utw\u00f3rz instancj\u0119 klasy, kt\u00f3r\u0105 chcesz przetestowa\u0107,<\/li>\n<li>Ustaw warto\u015b\u0107 zmiennej,<\/li>\n<li>Pobierz instancj\u0119 <strong>ReflectionClass<\/strong> dla klasy, kt\u00f3r\u0105 chcemy przetestowa\u0107,<\/li>\n<li>Ustaw jego w\u0142a\u015bciwo\u015b\u0107 na dost\u0119p,<\/li>\n<li>Przeczytaj warto\u015b\u0107.<\/li>\n<\/ol>\n<p>Oto szereg element\u00f3w, kt\u00f3re dostarcz\u0105 krok\u00f3w niezb\u0119dnych do tego.<\/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\">Utw\u00f3rz instancj\u0119 klasy<\/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\">Ustaw warto\u015b\u0107<\/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\">tworzenie odbitych obiekt\u00f3w<\/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\">Ustaw w\u0142a\u015bciwo\u015b\u0107, oznacz j\u0105 jako dost\u0119pn\u0105<\/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\">Przeczytaj warto\u015b\u0107<\/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>I to jest podstawowy elementarz refleksji<\/h2>\n<p>W tym momencie powinno to da\u0107 ci kilka podstawowych informacji na temat tego, czym jest Reflection, jak z niego korzysta\u0107 i dlaczego jest przydatny zw\u0142aszcza w przypadku <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">test\u00f3w jednostkowych<\/a><\/strong>.<\/p>\n<p>Jest to jedna z tych koncepcji, kt\u00f3ra mo\u017ce sta\u0107 si\u0119 bardziej z\u0142o\u017cona, poniewa\u017c API refleksji PHP jest do\u015b\u0107 pot\u0119\u017cne (ale stosunkowo \u0142atwe do zrozumienia). Kiedy jednak po\u0142\u0105czysz to z testowaniem jednostkowym, mo\u017cesz zrobi\u0107 wiele rzeczy.<\/p>\n<h3>Moja bezwstydna wtyczka<\/h3>\n<p>Maj\u0105c to na uwadze, je\u015bli jeste\u015b zainteresowany nauk\u0105 tajnik\u00f3w tego rodzaju rzeczy, nie wahaj si\u0119 sprawdzi\u0107 tylko dla <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">cz\u0142onk\u00f3w<\/a><\/strong> obszaru witryny. Ka\u017cdego tygodnia <strong><a href=\"https:\/\/tommcfarlin.com\/members-only-content\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tworz\u0119 zaleg\u0142o\u015bci,<\/a><\/strong> kt\u00f3re pomog\u0105 nam skupi\u0107 si\u0119 na przyj\u0119ciu lepszych praktyk jako programi\u015bci WordPress.<\/p>\n<p>Testy jednostkowe, refleksje i nie tylko to tylko najnowsza cz\u0119\u015b\u0107 tego.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zrozumienie podstaw refleksji w PHP mo\u017ce znacznie u\u0142atwi\u0107 programowanie, zw\u0142aszcza testowanie.<\/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":[721,897,805],"tags":[1169],"class_list":["post-229807","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-kod","category-php-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229807","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=229807"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229807\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/164037"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=229807"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=229807"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=229807"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}