Waarom mocken
Bij het schrijven van tests zijn er handelingen die je niet echt wilt uitvoeren, zoals e-mail versturen, de cache lezen en schrijven of externe API’s aanroepen. Het vervangen van zulke handelingen door “een nepobject dat zich als het echte voordoet” heet mocken. De voordelen van mocken zijn als volgt:- Tests zijn snel — er worden geen externe services of zware processen uitgevoerd, dus tests zijn zo klaar
- Tests zijn stabiel — ze zijn niet afhankelijk van de toestand van externe services en geven altijd hetzelfde resultaat
- De testscope is duidelijk — je kunt precies één klasse of methode verifiëren
Mockobjecten
Om objecten te mocken die via de servicecontainer worden geïnjecteerd, bind je een mockinstantie aan de container. De container gebruikt dan de mockinstantie in plaats van het object zelf aan te maken.De mock()-methode
Met de mock()-methode van de basistestklasse van Laravel schrijf je hetzelfde als hierboven beknopter.
De partialMock()-methode
Wil je slechts een deel van de methoden van een object mocken, gebruik dan partialMock().
Niet-gemockte methoden worden gewoon uitgevoerd.
De spy()-methode
Een spy lijkt op een mock, maar verschilt doordat je de interacties verifieert ná het uitvoeren van de code.
Waar een mock vooraf vastlegt “deze methode zou moeten worden aangeroepen”, controleert een spy achteraf “of deze methode is aangeroepen”.
Facades mocken
Anders dan gewone statische methodeaanroepen kunnen facades worden gemockt. Je krijgt dezelfde testbaarheid als bij dependency injection, maar met een beknoptere syntaxis. Neem als voorbeeld een controller die de cache gebruikt.get-methode van de Cache-facade te mocken gebruik je expects().
Facade-spies
Om een facade met een spy te observeren roep je despy()-methode van de betreffende facade aan.
Spies zijn handig wanneer je interacties wilt verifiëren nadat de code is uitgevoerd.
De tijd manipuleren
Wanneer je in tests tijdsafhankelijke logica verifieert, is het handig om de tijd dienow() of Carbon::now() teruggeeft te kunnen wijzigen.
De basisklasse voor feature-tests van Laravel biedt helpers voor het manipuleren van tijd.
travel() — door de tijd reizen
Tijdreizen met een closure
Geef je een closure door aan een tijdreismethode, dan wordt de tijd op het opgegeven tijdstip stilgezet, de closure uitgevoerd en daarna teruggekeerd naar de oorspronkelijke tijd.freezeTime() — de tijd stilzetten
freezeTime() legt de huidige tijd vast. freezeSecond() legt de huidige tijd vast op het begin van de seconde.
Praktijkvoorbeeld: inactieve threads vergrendelen
Tijdmanipulatie is nuttig voor het testen van functionaliteit zoals een forum waar posts worden vergrendeld na een periode van inactiviteit.Tijdmanipulatiemethoden zoals
travel() zijn alleen te gebruiken in feature-tests (klassen die overerven van Tests\TestCase). In de basistestklasse TestCase van PHPUnit werken ze niet.