, refactoring arv kode: del 4 - vores første enhed prøver,,,,, 51,,,,,,,,, 18,,,,,,,,,, det cyber - mandag envato tuts + kurser vil blive reduceret til $3.- og' t miss. denne post er en del af en serie kaldet refactoring arv kode. refactoring arv kode: del 3 - kompleks conditionalsrefactoring arv kode: del 5 - vildt og' s testbare metoder, gamle kodeks.grim kode.komplicerede regler.spaghetti - koden.det nonsens.i to ord, arv - koden.det er en serie, der vil hjælpe dig, arbejde og klare det.,,, en af de vigtigste øjeblikke i refactoring helt arv kode er, når vi begynder at få små stykker af det og begynde at skrive målrettet enhed prøver for disse små stykker.men det kan være meget vanskeligt, især når man har koden, som er affattet således, at det ville være vanskeligt at udarbejde eller løbe, hvis dele af det er forsvundet.vi kan ikke sikkert gøre store operationer på en kode, vi stadig ikke forstår, og kun en gylden mester test holder os at bryde det totalt.heldigvis er der nogle teknikker, der kan hjælpe os. hvad er en enhed?, i hele den historie automatiserede test, de sidste 20 år eller så, begrebet enhed test, blev defineret på mange måder.oprindeligt var det om kodeksens anvendelsesområde udøves i en test.en enhed - testen var en test, der testes mindst mulig enhed i et særligt programmeringssprog. i denne henseende, for vores php kode, en enhed test er en prøve, som udøver en enkelt funktion eller metode.når vi planlægger i en genstand orienterede stil, vores funktioner er organiseret i klasser.alle prøvninger, der er forbundet med en enkelt kategori betegnes som regel en prøvesag,.,, der er ca. 25 andre definitioner til betegnelse af enhed test, så vi vil ikke gå ind på hver enkelt.mens disse definitioner er helt forskellige, men alle har to ting til fælles.dette fører os til den nok mest accepteret definition.,, en enhed test er en prøve, som løber i millisekunder og prøver et stykke kode i isolation., må vi bemærke to nøgleord i definitionen: millisekunder - vores test skal løbe hurtigt, meget hurtigt, og isolation - vi må teste vores kode som isoleret som muligt.disse to centrale ord gå hånd i hånd, for for at gøre forsøg hurtigere er vi nødt til at reducere deres anvendelsesområde.databaser, net kommunikation, brugergrænseflader, de er for langsomme til at blive testet på denne måde.vi er nødt til at finde og isolere en lille bid af adfærdskodeks, således at vi kan indsamle (hvis nødvendigt) og løber den kode i den rækkefølge, der er millisekunder i mindre end ti millisekunder, for det ville være en centisecond.vores test rammer vil tilføje en lille op over den rene løbe tid af koden, men det er ubetydeligt.,, identifikationskode til enhed, der afprøves, at isolerede metoder, hvis struktur af kode tilladelser, anbefales det at begynde med at skrive test for hvad kode vi rent faktisk kan teste.det vil hjælpe os med at begynde at opbygge dækning, og det vil også tvinge os til at koncentrere sig og forstå små stykker af koden.husk, vi er refactoring, ønsker vi ikke at ændre adfærd.faktisk, at dette første skridt, vi ønsker ikke at ændre vores produktions - kode til alle, hvis det er muligt, er vi nødt til at analysere vores tre sager for at se, hvad vi kan teste og hvad ikke.,,, gamerunner.php, har stort set ingen logik.vi skabte det for at være en delegation.kan vi prøve det?ja, vi kunne.skal vi prøve det?nej, vi skal ikke. selv om nogle metoder kan, i teknisk henseende, testes, hvis der ikke er nogen logik i dem, er vi sikkert ikke ønsker at prøve dem.,,, runnerfunctions.php, er en helt anden historie.der er to funktioner., run(), er en stor opgave, det hele løbe af systemet.det er ikke noget, vi kan let test.og det er ingen tilbagevenden værdi, det er bare output til skærmen, så ville vi være nødt til at fange output og sammenligne tråde.det er ikke meget typisk for enhed test.på den anden side iscurrentanswercorrect(), returnerer et enkelt sandt eller falsk baseret på visse betingelser.kan vi prøve det?,, funktion iscurrentanswercorrect() ($minanswerid = 0 $maxanswerid = 9 $wronganswerid = 7 afkast rand ($minanswerid, $maxanswerid).= $wronganswerid;}, vi ved allerede, at denne kodeks er et vilkårligt nummer og sammenligner det med det id af forkert nummer.,,, trin 1, gå til den, goldenmastertest.php og mark alle prøvninger, som er sprunget.vi ønsker ikke at løbe dem for øjeblikket.vi begynder med at bygge enhed prøver, vi løber vores gyldne mester mere sjældent.vi skriver nye test, og vi kan ikke ændre produktions - kode, hurtige tilbagemeldinger er vigtigere.,,, trin 2, - skabe en ny test runnerfunctionstest.php i vores test, fortegnelse, sammen med goldenmastertest. folkesundhedsprogrammet.tænk på den enklest mulige test kode, som du kan skrive.hvad er det absolutte minimum for at få den til at køre?nå, det er sådan noget, require_once __dir__. "/... /quizzer /php /runnerfunctions. folkesundhedsprogrammet "klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() {}}, vi kræver, runnerfunctions.php, fil, så vi tester det kan medtages og producerer ikke en fejl.resten er ren boilerplate, bare et skelet klasse og en tom test funktion.men, hvad nu?hvad gør vi nu?ved du, hvordan kan vi narre, rand(), til at vende tilbage til det, vi ønsker?jeg ved det ikke endnu.så lad os undersøge, hvordan det er at arbejde lige nu. vi ved, hvordan man frø tilfældige generator, og hvad så, hvis vi forsøger at frø med nogle tal, ville det virke?vi kan skrive koden i vores prøve for at finde ud af, hvordan det virker.,, funktion testitcanfindcorrectanswer() {srand (0); var_dump (rand (0,9)); srand (1); var_dump (rand (0,9)); srand (2); var_dump (rand (0,9)); srand (3); var_dump (rand (0,9)); srand (4); var_dump (rand (0,9)}, ved vi også, at vores spørgsmål id er mellem 0 og ni.det giver den produktion under.,, int (8) int (8) int (7) int (5) int (9), men det ser ikke særlig klart.faktisk kan jeg ikke se nogen logik om, hvordan kunne vi fastsætte værdier, rand(), funktion vil medføre.vi bliver nødt til at ændre vores produktions - kode, så vi kan give de værdier, vi har brug for.,, afhængighed og afhængighed, injektion, når folk taler om "afhængighed", de synes om forbindelser mellem klasser.det er den mest almindelige tilfælde, især i mål orienterede programmering.men hvad hvis vi generalisere udtrykket lidt.glem klasser, glem objekter udelukkende koncentrere sig om betydningen af "afhængige".hvad er vores, rand (min max), metode afhænger af?det afhænger af to værdier.en mindste og største.,, kan vi kontrollere, rand() af disse to parametre?ikke, rand(), forudsigeligt vende tilbage til det samme nummer, hvis min og max er den samme?lad os se,.,, funktion testitcanfindcorrectanswer() {var_dump (rand (0,0)); var_dump (rand (1,1)); var_dump (rand (2,2)); var_dump (rand (3)); var_dump (rand (4,4)}, hvis vi har ret, hver linje skal smide et nummer fra nul til fire i en forudsigelig måde, int (0) europarl.eu.int int (1) (2) (3) europarl.eu.int int (4), det ser ret forudsigelig til mig.ved at sende det samme nummer for min og max, rand(), kan vi være sikre på, at vi skaber det forventede antal.hvordan gør vi det for vores funktion?det er ingen parametre.,, sandsynligvis den mest almindelige måde at injicere afhængighedsforhold til en metode er at anvende parametre med standardværdier.dette vil bevare funktion er nuværende funktion, men vil give os mulighed for at kontrollere dens strøm, når vi tester det.,, funktion iscurrentanswercorrect ($minanswerid = 0, $maxanswerid = 9) ($wronganswerid = 7 afkast rand ($minanswerid, $maxanswerid).= $wronganswerid;}, en ændring af, iscurrentanswercorrect(), på denne måde vil bevare sin nuværende adfærd og give os mulighed for at afprøve det på samme tid.du kan give din gyldne mester og styrer det nu.produktionen kode blev ændret, er vi nødt til at være sikker på, at vi ikke bryde det, som vores, iscurrentanswercorrect() ser ud nu, afprøvning, det er bare et spørgsmål om at sende 10 værdier for hver af de mulige tilbage, rand(),.,, funktion testitcanfindcorrectanswer() {$- > asserttrue (iscurrentanswercorrect (0,0)); $- > asserttrue (iscurrentanswercorrect (1,1) $- > asserttrue (iscurrentanswercorrect (2,2) $- > asserttrue (iscurrentanswercorrect (3)); $- > asserttrue (iscurrentanswercorrect (4,4) $- > asserttrue (iscurrentanswercorrect (5,5) $- > asserttrue (iscurrentanswercorrect (6,6) $- > assertfalse (iscurrentanswercorrect (7,7) $- > asserttrue (iscurrentanswercorrect (8,8));$- > asserttrue (iscurrentanswercorrect (9,9)}, at test funktion blev bygget af forvaltningen af vores test efter hver linje.nu, hvor vores test er meget stærkt, at vi kan køre dem næsten konstant.der er faktisk værktøjer til prøver, så snart en fil ændringer, og jeg har hørt om programmører, som styrer deres test kontinuerligt og de glimt på testen status bar ved udgangen af hver kommando.som det program, du ved, hvad de kan forvente, hvis testen ikke bliver grøn, da du troede, det, du gjorde noget forkert.deres feedback - er det næsten en selvfølge, at noget gik galt i sidste linje eller kommando, de skrev,.,, selvom det kan lyde ekstreme prøvekørt udvikling, jeg kan forestille mig, at det er nyttigt, især når man udvikle algoritmer.personligt foretrækker jeg at køre min test ved at trykke på en genvej, en enkelt nøgle genvej.og som prøver at hjælpe mig udvikle programmer, min genvej til prøver, f1,.,, lad os komme tilbage til sagen.den prøve, med ti påstande, løber i 66 ms, ca. 6,6 ms pr. påstand.hver påstand opkald og udfører et stykke af vores kodeks.det ser ud til at være, som vi har defineret enhed prøver i begyndelsen af denne forelæsning.,, fandt du den, assertfalse() med nummer syv?jeg vil vædde på halvdelen af, du gik glip af det.det er begravet dybt inde i en masse andre påstande.svært at se.jeg synes, at det fortjener sin egen prøve, så vi udtrykkeligt den fælles forkert svar.,, funktion testitcanfindcorrectanswer() {$- > asserttrue (iscurrentanswercorrect (0, 0) $- > asserttrue (iscurrentanswercorrect (1, 1) $- > asserttrue (iscurrentanswercorrect (2) $- > asserttrue (iscurrentanswercorrect (3, 3) $- > asserttrue (iscurrentanswercorrect (4, 4) $- > asserttrue (iscurrentanswercorrect (5, 5) $- > asserttrue (iscurrentanswercorrect (6)); $- > asserttrue (iscurrentanswercorrect (8, 8) $- > asserttrue (iscurrentanswercorrect (9, 9)} funktion testitcanfindwronganser() {$- > assertfalse (iscurrentanswercorrect (7, 7)), refactoring test, som vier i færd med refactoring, kode bedre og lettere at forstå, og vi må ikke glemme vores prøver.de er lige så vigtige som vores produktion.vi er nødt til at holde vores tests, ren og let at forstå.vi er nødt til at refactor vores tests, og vi skal gøre det, så snart vi observere, der er noget galt med dem og kun, når de passerer.på denne måde kan kontrollere produktionen kode vores prøver.hvis vi har en grøn test, vi refactor, og den bliver rød, vi slog den test.vi kan bare lave et par skridt og prøv igen. vi kunne få det korrekte svar antallet til et system og til at give korrekte svar.,, funktion testitcanfindcorrectanswer() ($correctanserids = [0, 1, 2, 3, 4, 5, 6, 8, 9]; for hvert ($correctanserids som $id) ($- > asserttrue (iscurrentanswercorrect ($id $id)}}, det går, men også indfører en logik.måske kunne vi tage den i en speciel påstand.dette kan være en lille smule ekstrem for sådan en enkel test, men det er en god lejlighed til at forstå begrebet.,, funktion testitcanfindcorrectanswer() ($correctanserids = [0, 1, 2, 3, 4, 5, 6, 8, 9] $- > assertanswersarecorrectfor ($correctanserids);} funktion testitcanfindwronganser() {$- > assertfalse (iscurrentanswercorrect (7, 7));} privat funktion assertanswersarecorrectfor ($correctanserids) (for hvert ($correctanserids som $id) ($- > asserttrue (iscurrentanswercorrect ($id $id)}}, det hjalp os på to måder.det første, vi flyttede logikken om hen over hvert enkelt element i en kontrol af det system til et privat metode.som vi plejer at holde vores private metoder ved udgangen af den klasse, ude af syne, ud af vejen for større logik i den offentlige midler, er det lykkedes os at stige fremstilling af vores test.i denne testmetode, vi er ligeglade med, hvor svarene er kontrolleret for korrekthed.vi bekymrer os om de papirer, som burde være korrekte svar.den anden fordel er, at gennemførelsen af præparatet.at holde det korrekte svar id i testen, hjalp os med separate oplysninger om gennemførelse fra, vi er nødt til at prøve.,, test til produktion kode afhængighed, en af de mest almindelige fejl nogen af os forpligter når test er at gentage, hvad der er i produktion.dette er et tilfælde af både kode dobbeltarbejde og en skjult afhængighed, normalt på visse værdier eller konstanterne.i vores tilfælde afhængighed er svaret id, der repræsenterer det forkerte svar.,, men at bevise denne afhængighed?ved første blik synes det kun en simpel gentagelse af en enkelt værdi.for at besvare dit dilemma, spørg dig selv: "skal jeg prøver ikke, hvis jeg beslutter at ændre den forkerte svar er id?",.svaret er naturligvis nej. ændrer en simpel konstant i produktionen kode ikke vil påvirke adfærd eller logik.således er den test skal ikke mislykkes. det lyder godt.men hvordan gør man det?- den simpleste måde er at afsløre de ønskede variable som en offentlig klasse variabel, bedre statisk eller konstant.i vores tilfælde, som vi har ingen klasse, kan vi bare gøre det globale variable eller faste.,, include_once __dir__. "/leg. php; denne wrong_answer_id = 7; funktion iscurrentanswercorrect ($minanswerid = 0, $maxanswerid = 9) {tilbage rand ($minanswerid, $maxanswerid).= wrong_answer_id;} funktion run() (//...//}, først ændre, runnerfunctions.php, fil, så iscurrentanswercorrect(), vil bruge en konstant i stedet for en lokal variabel.så løb din enhed prøver.dette sikrer os, at den ændring, som vi gjorde for produktionen kode ikke ødelægge noget.nu er det tid til prøven.,, funktion testitcanfindwronganswer() {$- > assertfalse (iscurrentanswercorrect (wrong_answer_id, wrong_answer_id)}, ændre, testitcanfindwronganswer(), til at anvende samme konstant.i sagen, runnerfunctions.php, er medtaget i begyndelsen af testen fil den angivne konstant vil være tilgængelige for testen.,, refactoring test (igen), nu, at vi er afhængige af, wrong_answer_id, for vores, testitcanfindwronganswer(), burde vi ikke refactor vores test, så testitcanfindcorrectanswer(), også afhængig af den samme konstant?ja, vi skal.det vil ikke blot gøre vores test, lettere at forstå, og det vil også gøre det mere robust.ja, for hvis vi vil vælge et forkert svar på id - kort, der allerede er på listen over korrekte svar er defineret i prøve, at særlige tilfælde ville dumpe, selv om produktionen kode stadig ville være korrekt. klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() ($correctanserids = $- > getgoodanswerids(); $- > assertanswersarecorrectfor ($correctanserids)} privat funktion getgoodanswerids() {afkast [0, 1, 2, 3, 4, 5, 6, 8, 9]}},, samtidig med at antallet af det korrekte svar på prøven funktion var i sig selv en god idé på et eller andet tidspunkt, som vi ændrer vores test til at påberåbe sig mere og mere på de værdier, der er fastsat i produktionen kode, er vi også -nt at skjule oplysninger om tallene.det første skridt er at anvende en metode, ekstrakt, refactoring og få det i sin egen metode.,, klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() ($correctanserids = $- > getgoodanswerids(). $- > assertanswersarecorrectfor ($correctanserids)} privat funktion getgoodanswerids() {tilbage array_diff (interval (0,9) [wrong_answer_id]);), ændrede vi, getgoodanswerids(), betydeligt.for det første har vi en liste med range(), i stedet for at skrive alle mulige id - kort i hånden.så vi trækkes fra den mængde det element, der indeholder, wrong_answer_id,.den liste over korrekte svar id er også uafhængig af den værdi, der er fastsat i den forkerte svar. men er det nok?hvad med den minimale og maksimale id?kan vi ikke få dem på samme måde.nå, lad os se.,, include_once __dir__. "/leg. php; denne wrong_answer_id = 7; denne min_answer_id = 0; denne max_answer_id = 9; funktion iscurrentanswercorrect ($minanswerid = min_answer_id, $maxanswerid = max_answer_id) {tilbage rand ($minanswerid, $maxanswerid).= wrong_answer_id;} funktion run() (//...//}, det ser ret sød.konstanterne kun blev anvendt som standardværdier for parametre for funktion, iscurrentanswercorrect(),.dette giver os mulighed for at tilføre de nødvendige værdier ved test, og det er også helt klart, hvad disse parametre.som en god bivirkning, en lille del af konstanterne i toppen af sagen begyndte at fremhæve de centrale værdier, som vores, runnerfunctions.php, fil anvendelser.flot!, glem ikke at give fra den gyldne mester test, testoutputmatchesgoldenmaster(), test funktion.konstanterne indførte vi kun anvendes i den gyldne mester test.vores enhed prøver faktisk genvej disse værdier altid., skal vi nu til at ajourføre vores enhed prøve at bruge konstanter.,, klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() ($correctanserids = $- > getgoodanswerids(). $- > assertanswersarecorrectfor ($correctanserids)} privat funktion getgoodanswerids() {tilbage array_diff (interval (min_answer_id, max_answer_id) [wrong_answer_id])), var det enkle og ligetil.vi var nødt til at ændre de parametre, range() metode.det sidste skridt, vi kan gøre med vores test, er at rydde op i det rod, vi efterlod vores, testitcanfindcorrectanswer() metode.,, funktion testitcanfindcorrectanswer() ($correctanserids = $- > getgoodanswerids(). $- > assertanswersarecorrectfor ($correctanserids)}, kan vi iagttage to store problemer med denne kode.først en uoverensstemmelse i navngivningen.når vi kaldte svar, korrekt, og så vi kaldte dem godt.vi skal beslutte, om den ene af de to.grammatisk korrekt synes at være mere passende.som det korrekt er det modsatte af fejl, mens godt er det modsatte af dårlig.,, klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() ($correctanserids = $- > getcorrectanswerids(). $- > assertanswersarecorrectfor ($correctanserids)} privat funktion getcorrectanswerids() {tilbage array_diff (interval (min_answer_id, max_answer_id), [wrong_answer_id]);}}, vi til vores private metode i overensstemmelse med ovenstående begrundelse.men det er ikke nok.vi er nødt til at løse et problem.vi giver den tilbage til værdien af en privat metode til en variabel, bare for at bruge det samme variabel for den næste linje.og det er kun anvendelse for variabel.i vores tilfælde den variable var der, fordi det gav ekstra afklaring om, hvad en række tal mente.det var dets anvendelse og anvendelsesområde.men nu, hvor vi har en metode med næsten samme navn, giver udtryk for den samme koncept, den variable overlevet sig selv.det er en nødvendig opgave.,,,,,, vi kan bruge i overensstemmelse med variabel, refactoring for at fjerne de variable og kalde den metode direkte i stedet for at bruge den variable på den næste linje.,, klasse runnerfunctionstest udvider phpunit_framework_testcase {funktion testitcanfindcorrectanswer() {$- > assertanswersarecorrectfor ($- > getcorrectanswerids())} private funktion getcorrectanswerids() {tilbage array_diff (interval (min_answer_id, max_answer_id) [wrong_answer_id]);}}, nu, hvad er fedt her, er, at vi begyndte med kun to linjer kode, der ikke var klart, og det var forurenet af dobbeltarbejde og en skjult afhængighed.efter et par skridt for de ændringer, vi endte med to linjer kode, men vi slog den afhængighed af den numeriske id - numre.er det fedt, eller hvad?,, at løbe, er vi færdige med den, runnerfunctions. php,?hvis jeg ser en, if(), betyder det, at logik.hvis jeg kan se logikken: en enhed, der er nødvendig for at kontrollere den test.og vi har en, if(), i vores run(), metode er, do- while(), loop.det er tid til at bruge vores ide 's refactoring redskab til at udtrække en metode og afprøve det.,, men det stykke kode skal vi ud?ved første øjekast alene betinget angivelse, er en god idé.dette fører til den kode nedenfor.,, funktion run() ($notawinner. $agame = nye game(). $agame - > der tilsættes ("chet"); $agame - > der tilsættes (pat) $agame - > der tilsættes ("sue"); gøre {$terninger. = rand (0, 5) + 1 $agame - > rulle ($terninger); $notawinner = getnotwinner ($agame)}, mens ($notawinner)} funktion getnotwinner ($agame) (hvis (iscurrentanswercorrect()) ($notawinner = $agame - > wascorrectlyanswered(); tilbage $notawinner;} andre ($notawinner = $agame - > wronganswer(); tilbage $notawinner;}}, mens det ser ret god, og det blev skabt ved bare at vælge den rigtige menupunkt fra vores ide, der er et problem, der bekymrer mig.det, agame, objekt anvendes både i, mens, loop - og både i det ekstraherede metode.hvad med det her?,, funktion run() ($notawinner. $agame = nye game(). $agame - > der tilsættes ("chet"); $agame - > der tilsættes (pat) $agame - > der tilsættes ("sue"); gøre {$terninger = rand (0, 5) + 1 $notawinner = getnotwinner ($agame $terninger)}, mens ($notawinner)} funktion getnotwinner ($agame $terninger) ($agame - > rulle ($terninger); hvis (iscurrentanswercorrect()) ($notawinner = $agame - > wascorrectlyanswered() tilbage notawinner dollars;;) andet ($notawinner = $agame - > wronganswer(); tilbage $notawinner;}}, denne løsning fjerner den, agame, genstand fra inderkredsen.det indfører andre slags problemer.vores parameter tæller stiger.nu er vi nødt til at sende, $terninger.mens antallet af parametre, to, er så lave, at de ikke medfører nogen bekymringer, må vi også tænke på, hvordan de parametre, der anvendes i selve metoden.- terninger, anvendes kun, når, roll(), metode anmodes om, agame,.mens, roll(), metode har stor betydning i kampen, klasse, det er ikke det, der beslutter, hvis vi har en vinder eller ej.ved analyse af koden, spil, kan vi konkludere, at en medlemsstat kan være sand vinder kun ved at wascorrectlyanswered(),.det er mærkeligt, og det understreges, at nogle alvorlige spørgsmål i spillet, klasse vi vil behandle i en kommende lektion.,, der er baseret på alle de ovennævnte bemærkninger, er det sandsynligvis bedre at gå med den første version af vores ekstraheret metode.,, funktion getnotwinner ($agame) (hvis (iscurrentanswercorrect()) {% notawinner = $agame - > wascorrectlyanswered(); tilbage $notawinner;} andre ($notawinner = $agame - > wronganswer(); tilbage $notawinner;}}, kan vi tro på vores ide og ved bare at kigge på den kode, vi kan være ret sikker på, det er i stykker.hvis du føler dig usikker, bare løbe din gyldne mester test.lad os fokusere på at skabe nogle tests for dette fine metode.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() {}, jeg kom med dette navn ved at omdanne det, jeg vil prøve i testmetoden navn.det er meget vigtigt at navngive din test, hvad opførsel bør de test og ikke om, hvad de vil gøre.dette vil hjælpe andre eller dig selv seks måneder fra nu, for at forstå, hvad det lille stykke kode egentlig skal gøre, men vi har et problem.vores afprøvede metode har brug for et objekt.vi er nødt til at køre det sådan:,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($agame =???getnotwinner ($agame)}, har vi brug for en $agame, genstand for type, spil.men vi gør en enhed test, ønsker vi ikke at bruge de rigtige, kompleks og dårligt forstået, spil, klasse.dette fører os til et nyt kapitel i test, vi vil tale om i en anden lektie:, spottende stubbing og rigtigt.disse er alle metoder til at skabe og test objekt ved hjælp af andre genstande, der opfører sig på en forud fastlagt måde.under anvendelse af en ramme eller endog phpunit egen indbyggede muligheder kan være til hjælp for vores nuværende viden til vores meget enkle test, kan vi gøre en ting glemmer mange mennesker,.,, kan vi skabe en klasse, der svarer til kamp i vores test fil og definere den kun to metoder, vi er interesserede i.det er meget simpelt.,, klasse runnerfunctionstest udvider phpunit_framework_testcase (//...//funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($agame = nye fakegame(); getnotwinner ($agame)} //...//} klasse fakegame {funktion wascorrectlyanswered() {} funktion wronganswer() {}}, dette er vores test alvorligt, og vi er stadig i millisekund zone.bemærk, at de to sprang test er dem fra den gyldne mester.,,: 43 ms, hukommelse: 3.00mb okay, men ufuldstændige eller ikke - test.test: 5, påstande: 10, sprang: 2.,, selv om vi skulle nævne vores klasse forskelligt fra, spil, for vi kan ikke erklære den samme klasse to gange, koden er ret enkelt.vi har defineret de to metoder, vi er interesserede i.det næste skridt er at give det tilbage, og test for det.men det kan være vanskeligere end forventet på grund af denne linje kode:,, hvis (iscurrentanswercorrect()), vores metode kræver, iscurrentanswercorrect() uden nogen parametre.det er skidt for os.vi kan ikke styre sin produktion.det vil blot skabe tilfældige tal.vi er nødt til at refactor vores kode lidt, før vi kan fortsætte.vi er nødt til at flytte til denne metode i løkken og videregive resultatet som en parameter, getnotwinner(),.dette vil gøre det muligt for os at kontrollere resultatet af udtryk i ovenstående, hvis udtalelse, således at den kanal, som vores kodeks vil gå ned.vores første test, vi har brug for det til at komme ind og ringer, hvis, wascorrectlyanswered(),.,, funktion run() (//...////////- {$terninger = rand (0, 5) + 1 $agame - > rulle ($terninger); $notawinner = getnotwinner ($agame, iscurrentanswercorrect())}, mens ($notawinner)} funktion getnotwinner ($agame, $iscurrentanswercorrect) (hvis ($iscurrentanswercorrect) {% notawinner = $agame - > wascorrectlyanswered(); tilbage $notawinner;} andre ($notawinner = $agame - > wronganswer(); tilbage $notawinner;}}, nu har vi kontrol, alle områder i stykker.det er tid til testning.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($agame = nye fakegame(). $iscurrentanswercorrect = sandt. $- > asserttrue (getnotwinner ($agame, $iscurrentanswercorrect)}, er dette en at test, flot.vi vender tilbage, fra vores tilsidesat metode, selvfølgelig.,, funktion wascorrectlyanswered() {tilbage.}, er vi nødt til at prøve den anden vej gennem, if(),.,, funktion testitcantellifthereisnowinnerwhenawronganswerisprovided() ($agame = nye fakegame(). $iscurrentanswercorrect = falske $- > assertfalse (getnotwinner ($agame, $iscurrentanswercorrect)}, vi valgte at prøve forkert denne gang, så vi skelne mellem to tilfælde lettere.,, klasse fakegame {funktion wascorrectlyanswered() {tilbage.} funktion wronganswer() {tilbage falske}}, og vores, fakegame, blev ændret i overensstemmelse hermed,.,, endelige rengøring,, refactoring ekstraheret metode, er vi næsten vede. undskyld for at få denne lektion i så lang tid, håber jeg, at du kunne lide det, og kunne ikke falde i søvn.endelige ændringer inden indgåelsen af den, runnerfunctions.php, fil og dens undersøgelser.,, funktion getnotwinner ($agame, $iscurrentanswercorrect) (hvis ($iscurrentanswercorrect) ($notawinner = $agame - > wascorrectlyanswered(); tilbage $notawinner;} andre ($notawinner = $agame - > wronganswer(); tilbage notawinner dollars.}}, er der nogle unødvendige opgaver i vores metode, vi skal rydde det op.vores enhed prøver at ændre denne meget sikker.,, funktion getnotwinner ($agame, $iscurrentanswercorrect) (hvis ($iscurrentanswercorrect) {tilbage $agame - > wascorrectlyanswered();} andre {tilbage $agame - > wronganswer();}}, vi anvendte de samme i overensstemmelse med variabel refactoring, og det førte til dens forsvinden.prøver stadig at vi stadig er under 100 ms for alle enhed prøver sammen.jeg siger, det er ret lækkert.,, refactoring test (igen), ja, ja, vi kan gøre vores prøve lidt bedre.da vi kun har et par linjer kode, vores refactorings bliver let.problemet er i kode nedenfor.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($agame = nye fakegame(). $iscurrentanswercorrect = sandt. $- > asserttrue (getnotwinner ($agame, $iscurrentanswercorrect)} funktion testitcantellifthereisnowinnerwhenawronganswerisprovided() ($agame = nye fakegame(). $iscurrentanswercorrect = falske $- > assertfalse (getnotwinner ($agame, $iscurrentanswercorrect)}, har vi endnu en kode til nye fakegame() i hver metode.tid til en ekstrakt metode.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($agame = $- > afakegame(). $iscurrentanswercorrect = sandt. $- > asserttrue (getnotwinner ($agame, $iscurrentanswercorrect)} funktion testitcantellifthereisnowinnerwhenawronganswerisprovided() ($agame = $- > afakegame(). $iscurrentanswercorrect = falsk og $- > assertfalse (getnotwinner ($agame, $iscurrentanswercorrect)}, her er $agame, variable temmelig ubrugelig.tid til i overensstemmelse med variabel.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() ($iscurrentanswercorrect = sandt. $- > asserttrue (getnotwinner ($- > afakegame(), $iscurrentanswercorrect)} funktion testitcantellifthereisnowinnerwhenawronganswerisprovided() ($iscurrentanswercorrect = falske $- > assertfalse (getnotwinner ($- > afakegame() - iscurrentanswercorrect)}, det gjorde vores kode kortere og mere aktive på samme tid.når vi læser en påstand, det lyder som en prosa.at hævde, at vi modtager, ikke sandt, vi kalder vi forsøge at få de ikke vinder ved hjælp af vores falske klasse med korrekte svar.hvad jeg ikke kan lide, er, at vi bruger samme variabel, og tillægger det, sand eller falsk, afhængigt af prøven.jeg mener, der bør være en mere udtryksfuld måde at gøre det på.,, funktion testitcantellifthereisnowinnerwhenacorrectanswerisprovided() {$- > asserttrue (getnotwinner ($- > afakegame() $- > acorrectanswer())} funktion testitcantellifthereisnowinnerwhenawronganswerisprovided() {$- > assertfalse (getnotwinner ($- > afakegame() $- > awronganswer()));), wow!vores analyser blev fælles foringer og de virkelig er udtryk for, hvad det er, vi prøver.alle detaljer er skjult i private metoder, ved afslutningen af testen.99% af de sager, som de ikke bekymrer sig om deres gennemførelse, og når du gør det, du kan bare, ctrl + klik på den metode, navn og den ide vil springe til gennemførelsen, tilbage til produktionen kode, hvis vi ser på vores loop, kan vi se, at der er en variabel, der kan slippe af med et blink med øjet, funktion run() ($notawinner. $agame = nye game(). $agame - > der tilsættes ("chet"); $agame - > der tilsættes (pat) $agame - > der tilsættes ("sue"); gøre {$terninger = rand (0, 5) + 1 $agame - > rulle ($$notawinner = getnotwinne terninger);
refactoring arv kode: del 4
Next Page:arbejde med kontrollører i symfony 2