{"id":229941,"date":"2022-11-28T16:29:00","date_gmt":"2022-11-28T13:29:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229941"},"modified":"2022-11-09T19:23:21","modified_gmt":"2022-11-09T16:23:21","slug":"en-primer-om-reflektion-i-php-och-hur-det-spelar-in-i-enhetstestning","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/en-primer-om-reflektion-i-php-och-hur-det-spelar-in-i-enhetstestning\/","title":{"rendered":"En primer om reflektion i PHP (och hur det spelar in i enhetstestning)"},"content":{"rendered":"\n<p>Under de senaste veckorna har jag skrivit om <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">enhetstestning<\/a><\/strong> f\u00f6r <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">medlemmarna<\/a><\/strong> p\u00e5 sajten (och n\u00e5got som jag planerar att forts\u00e4tta g\u00f6ra i n\u00e4sta inl\u00e4gg). Det \u00e4r n\u00e5got som jag tror; om du skriver kod p\u00e5 serversidan b\u00f6r du g\u00f6ra det.<\/p>\n<p>Naturligtvis \u00e4r det l\u00e4ttare f\u00f6r mig att s\u00e4ga det \u00e4n att g\u00f6ra det, s\u00e5 \u00e4ven om jag f\u00f6rs\u00f6ker se till att jag g\u00f6r ett bra jobb med det, finns det alltid utrymme f\u00f6r mig att f\u00f6rb\u00e4ttra. Jag s\u00e4ger det mer som en personlig magkontroll \u00e4n n\u00e5got annat, s\u00e5 jag avviker.<\/p>\n<p>Ett av de begrepp som ofta dyker upp under tester \u00e4r id\u00e9n om att testa v\u00e4rderingarna av privata attribut. L\u00e5t oss till exempel s\u00e4ga att du har en setter, men att du inte n\u00f6dv\u00e4ndigtvis har en getter f\u00f6r just det v\u00e4rdet.<\/p>\n<p>Det \u00e4r l\u00e4tt att s\u00e4ga &quot;Jaha, d\u00e5 m\u00e5ste du skriva en getter&quot;, men det \u00e4r inte alltid fallet. Jag menar om du lagrar information inom klassen som inte beh\u00f6ver exponeras f\u00f6r tredjepartsklasser?<\/p>\n<p>Hur ska vi d\u00e5 skriva tester mot den typen av data n\u00e4r vi vill komma \u00e5t den men inte har m\u00f6jlighet att g\u00f6ra det och inte vill \u00e4ventyra integriteten i v\u00e5rt arbete?<\/p>\n<p>Det \u00e4r d\u00e4r reflektion spelar in.<\/p>\n<h2>Reflektion i PHP<\/h2>\n<p>Specifikt, f\u00f6r att f\u00f6rst\u00e5 hur man inspekterar v\u00e4rdet p\u00e5 en given variabel utifr\u00e5n och in, m\u00e5ste man veta hur man anv\u00e4nder reflektion.<\/p>\n<p>Lyckligtvis ger PHP oss ett kraftfullt API f\u00f6r att g\u00f6ra det, och det \u00e4r f\u00f6rmodligen v\u00e4rt att g\u00e5 in p\u00e5 de djupa detaljerna om det i ett annat inl\u00e4gg. Men f\u00f6r den h\u00e4r, kommer att h\u00e5lla sig till grunderna.<\/p>\n<h3>En fungerande definition<\/h3>\n<p>F\u00f6rst en titt p\u00e5 vad reflektion betyder. PHP-manualen <strong><a href=\"https:\/\/php.net\/manual\/en\/class.reflectionclass.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">definierar det som<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Klassen <strong>ReflectionClass<\/strong> rapporterar information om en klass.<\/p>\n<\/blockquote>\n<p>Men jag tycker att det \u00e4r v\u00e4rt att ha n\u00e5got lite mer gediget. L\u00e5t oss g\u00e5 med n\u00e5got s\u00e5nt h\u00e4r \u00e5tminstone f\u00f6r det h\u00e4r inl\u00e4gget:<\/p>\n<blockquote>\n<p>Reflektion \u00e4r hur ett program ska inspektera sig sj\u00e4lv och modifiera sig sj\u00e4lv under k\u00f6rning.<\/p>\n<\/blockquote>\n<p>Kanske \u00e4r det inte bra; kanske inte.<\/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=\"En primer om reflektion i PHP (och hur det spelar in i enhetstestning)\" ><\/a><\/p>\n<p>Men det kommer att tj\u00e4na syftet med detta inl\u00e4gg.<\/p>\n<h3>L\u00e4sa ett v\u00e4rde via reflektion<\/h3>\n<p>L\u00e5t oss anta att du f\u00f6r det h\u00e4r inl\u00e4gget har en namnrymdsklass p\u00e5 <strong>AcmePluginAPIClient<\/strong> och den har en egenskap som heter <strong>anv\u00e4ndarnamn<\/strong>. Vi ska ta en titt p\u00e5 hur en mycket grundl\u00e4ggande implementering av detta kan se ut senare.<\/p>\n<p>Naturligtvis skulle det vara mycket mer konkretiserat i ett verkligt plugin.<\/p>\n<p>L\u00e5t oss dock s\u00e4ga att du vill st\u00e4lla in v\u00e4rdet p\u00e5 attributet och sedan l\u00e4sa dess v\u00e4rde. Varningen \u00e4r att fastigheten \u00e4r markerad som <strong>privat<\/strong> och det finns inget s\u00e4tt att l\u00e4sa den fr\u00e5n utsidan.<\/p>\n<p>Det \u00e4r h\u00e4r reflektion kommer v\u00e4l till pass. Det vill s\u00e4ga att vi kan anv\u00e4nda en del av programmet f\u00f6r att titta p\u00e5 sig sj\u00e4lvt och rapportera tillbaka vad det ser. (Reflektion, f\u00f6rst\u00e5r? Det \u00e4r som n\u00e4r vi vill veta vad som h\u00e4nder med oss \u200b\u200bsj\u00e4lva och ingen annan \u00e4r i n\u00e4rheten s\u00e5 vi tittar in i en spegel och ser vad som finns d\u00e4r.)<\/p>\n<p>F\u00f6r att g\u00f6ra detta m\u00e5ste du g\u00f6ra fem saker:<\/p>\n<ol>\n<li>Instantiera klassen du vill testa,<\/li>\n<li>St\u00e4ll in v\u00e4rdet p\u00e5 variabeln,<\/li>\n<li>Ta en instans av <strong>ReflectionClass<\/strong> f\u00f6r klassen vi vill testa,<\/li>\n<li>St\u00e4ll in dess egendom till tillg\u00e4nglig,<\/li>\n<li>L\u00e4s v\u00e4rdet.<\/li>\n<\/ol>\n<p>S\u00e5 h\u00e4r \u00e4r en serie sammanfattningar som ger de steg som kr\u00e4vs f\u00f6r att g\u00f6ra exakt det.<\/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\">Instantiera klassen<\/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\">St\u00e4ll in v\u00e4rdet<\/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\">Instantiera reflekterade objekt<\/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\">St\u00e4ll in egenskapen, markera den som tillg\u00e4nglig<\/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\">L\u00e4s v\u00e4rdet<\/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>Och det \u00e4r den grundl\u00e4ggande primern om reflektion<\/h2>\n<p>Vid det h\u00e4r laget b\u00f6r det h\u00e4r ge dig lite grundl\u00e4ggande information om vad Reflection \u00e4r, hur man anv\u00e4nder det och varf\u00f6r det \u00e4r anv\u00e4ndbart, s\u00e4rskilt n\u00e4r det g\u00e4ller <strong><a href=\"https:\/\/tommcfarlin.com\/tag\/unit-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">enhetstestning<\/a><\/strong>.<\/p>\n<p>Detta \u00e4r ett av de koncept som kan bli mer komplexa eftersom PHPs reflektions-API \u00e4r ganska kraftfullt (men relativt l\u00e4tt att f\u00f6rst\u00e5). Men n\u00e4r du kopplar ihop det med enhetstestning finns det m\u00e5nga saker som kan g\u00f6ras.<\/p>\n<h3>Min skaml\u00f6sa plugg<\/h3>\n<p>Med det sagt, om du \u00e4r intresserad av att l\u00e4ra dig in-och-outs f\u00f6r den h\u00e4r typen av saker, tveka inte att kolla in det omr\u00e5de <strong><a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">som endast \u00e4r f\u00f6r medlemmar<\/a><\/strong> p\u00e5 webbplatsen. Jag bygger, varje vecka, <strong><a href=\"https:\/\/tommcfarlin.com\/members-only-content\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en eftersl\u00e4pning av saker<\/a><\/strong> f\u00f6r att hj\u00e4lpa oss fokusera p\u00e5 att anamma b\u00e4ttre metoder som WordPress-utvecklare.<\/p>\n<p>Enhetstestning, reflektion och mer \u00e4r bara den senaste delen av det.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Att f\u00f6rst\u00e5 grunderna f\u00f6r reflektion i PHP kan hj\u00e4lpa till att g\u00f6ra din programmering, s\u00e4rskilt testning, mycket enklare.<\/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":[901,807,724],"tags":[1173],"class_list":["post-229941","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koda","category-php-9","category-utvecklaren","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=229941"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229941\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/164037"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=229941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=229941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=229941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}