MockK: Vysmievaná knižnica pre Kotlina

1. Prehľad

V tomto výučbe sa pozrieme na niektoré základné funkcie knižnice MockK.

2. MockK

V Kotline sú všetky triedy a metódy konečné. To nám síce pomáha písať nemenný kód, ale spôsobuje to aj určité problémy počas testovania.

Väčšina falošných knižníc JVM má problémy so zosmiešňovaním alebo zatĺkaním záverečných tried. Samozrejme môžeme pridať „otvorené”Kľúčové slovo pre triedy a metódy, ktoré sa chceme vysmievať. Ale zmena triedy iba na zosmiešnenie nejakého kódu sa nezdá byť najlepším prístupom.

Prichádza knižnica MockK, ktorá ponúka podporu pre jazykové vlastnosti a konštrukty jazyka Kotlin. MockK vytvára proxy pre vysmievané triedy. To spôsobí určité zníženie výkonu, ale celkové výhody, ktoré nám MockK poskytuje, stoja za to.

3. Inštalácia

Inštalácia je taká jednoduchá, ako len môže byť. Potrebujeme len pridať falošnú závislosť do nášho projektu Maven:

 io.mockk mockk 1.9.3 test 

Pre Gradle ho musíme pridať ako závislosť testu:

testImplementation "io.mockk: mockk: 1.9.3"

4. Základný príklad

Vytvorme službu, ktorú by sme chceli zosmiešňovať:

trieda TestableService {fun getDataFromDb (testParameter: String): String {// databáza dotazov a návrat zodpovedajúcej hodnoty} fun doSomethingElse (testParameter: String): String {návrat "Nechcem!" }}

Tu je príklad testu, ktorý sa vysmieva Testovateľná služba:

@Test fun givenServiceMock_whenCallingMockedMethod_thenCorrectlyVerified () {// given val service = mockk () every {service.getDataFromDb ("Expected Param")} returns "Expected Output" // when val result = service.getDataFromDb ("Expected Param") // potom overte {service.getDataFromDb ("Očakávaný parameter")} assertEquals ("Očakávaný výstup", výsledok)}

Na definovanie falošného objektu sme použili mockk () metóda.

V ďalšom kroku sme definovali správanie nášho falošného. Za týmto účelom sme vytvorili každý blok, ktorý popisuje, aká odpoveď by sa mala vrátiť pre ktoré volanie.

Nakoniec sme použili overiť blok na overenie, či sa vysmievanie vyvolalo, ako sme očakávali.

5. Príklad anotácie

Je možné použiť anotácie MockK na vytvorenie všetkých druhov falošných správ. Vytvorme službu, ktorá vyžaduje dve naše inštancie Testovateľná služba:

trieda InjectTestService {lateinit var service1: TestableService lateinit var service2: TestableService zábava invokeService1 (): String {return service1.getDataFromDb ("Test Param")}}

InjectTestService obsahuje dve polia rovnakého typu. Pre MockK to nebude problém. MockK sa snaží priradiť vlastnosti podľa názvu, potom podľa triedy alebo nadtriedy. To tiež nemá problém s vkladaním predmetov do súkromných polí.

Vysmievajme sa InjectTestService v teste pomocou anotácií:

trieda AnnotationMockKUnitTest {@MockK lateinit var služba1: TestableService @MockK lateinit var služba2: TestableService @InjectMockKs var objektUnderTest = InjectTestService () @BeforeEach zábava setUp () = MockKAnnotations.init (toto) // testy tu ...}

Vo vyššie uvedenom príklade sme použili @InjectMockKs anotácia. Toto určuje objekt, do ktorého sa majú vložiť definované falošné správy. V predvolenom nastavení vstrekuje premenné, ktoré ešte nie sú priradené. Môžeme použiť @OverrideMockKs prepísať polia, ktoré už majú hodnotu.

MockK vyžaduje MockKAnnotations.init (…) byť vyvolaný na objekte deklarujúcom premennú s anotáciami. Pre Junit5 môže byť nahradený @ExtendWith (MockKExtension :: trieda).

6. Špión

Spy umožňuje posmievať sa iba konkrétnej časti nejakej triedy. Môže sa napríklad použiť na vysmievanie konkrétnej metódy v Testovateľná služba:

@Test fun givenServiceSpy_whenMockingOnlyOneMethod_thenOtherMethodsShouldBehaveAsOriginalObject () {// dané val service = spyk () každý {service.getDataFromDb (any ())} vráti „Mocked Output“ // pri kontrole zosmiešňovanej metódy val firstResult = service.get firstDesult = service.get // potom assertEquals ("Mocked Output", firstResult) // pri kontrole nevysmievanej metódy val secondResult = service.doSomethingElse ("Any Param") // potom assertEquals ("nechcem!", secondResult)}

V príklade sme použili spyk metóda na vytvorenie špionážneho objektu. Mohli sme tiež použiť @ SpyK anotácia na dosiahnutie toho istého:

trieda SpyKUnitTest {@SpyK lateinit var služba: TestableService // Testy tu}

7. Uvoľnené Mock

Typický posmievaný predmet bude vrhať MockKException ak sa pokúsime zavolať metódu, kde návratová hodnota nebola zadaná.

Ak nechceme popísať správanie každej metódy, môžeme použiť uvoľnenú falošnú reakciu. Tento druh simulácie poskytuje predvolené hodnoty pre každú funkciu. Napríklad String návratový typ vráti prázdny String. Tu je krátky príklad:

@Test fun givenRelaxedMock_whenCallingNotMockedMethod_thenReturnDefaultValue () {// dané val service = mockk (relaxed = true) // when val result = service.getDataFromDb ("Any Param") // then assertEquals ("", result)}

V príklade sme použili posmech metóda s uvoľnene atribút vytvoriť uvoľnený falošný objekt. Mohli sme tiež použiť @RelaxedMockK anotácia:

trieda RelaxedMockKUnitTest {@RelaxedMockK služba lateinit var: TestableService // Testy tu}

8. Objekt Mock

Kotlin poskytuje jednoduchý spôsob deklarácie singletonu pomocou objekt kľúčové slovo:

objekt TestableService {fun getDataFromDb (testParameter: String): String {// databáza dotazov a návrat zhodnej hodnoty}}

Väčšina posmešných knižníc má však problém s vysmievaním sa Kotlinových singletonových inštancií. Z tohto dôvodu MockK poskytuje mockkObject metóda. Pozrime sa:

@ Testovacia zábava danýObject_whenMockingIt_thenMockedMethodShouldReturnProperValue () {// daný mockkObject (TestableService) // pri volaní neposmievanej metódy val firstResult = service.getDataFromDb ("Any Param") // potom vráti skutočnú odpoveď assertEquals (/ * DBR) // pri volaní vysmievanej metódy každý {service.getDataFromDb (any ())} vráti "Mocked Output" val secondResult = service.getDataFromDb ("Any Param") // potom vráti zosmiešnenú odpoveď assertEquals ("Mocked Output", secondResult)}

9. Hierarchické zosmiešňovanie

Ďalšou užitočnou vlastnosťou MockK je schopnosť zosmiešňovať hierarchické objekty. Najskôr vytvorme hierarchickú štruktúru objektov:

class Foo {lateinit var name: String lateinit var bar: Bar} class Bar {lateinit var nick: String}

The Foo trieda obsahuje pole typu Bar. Teraz môžeme štruktúru zosmiešniť iba v jednom jednoduchom kroku. Poďme sa posmievať názov a prezývka polia:

@Test fun givenHierarchicalClass_whenMockingIt_thenReturnProperValue () {// dané val foo = mockk {every {name} returns "Karol" every {bar} returns mockk {every {nickname} returns "Tomato"}} // // when val name = foo.name val prezývka = foo.bar.nickname // potom assertEquals ("Karol", meno) assertEquals ("Tomato", prezývka)}

10. Zachytávanie parametrov

Ak potrebujeme zachytiť parametre odovzdané metóde, môžeme použiť CapturingSlot alebo MutableList. Je to užitočné, keď chceme mať v logike nejakú vlastnú logiku odpoveď blok alebo len potrebujeme overiť hodnotu odovzdaných argumentov. Tu je príklad CapturingSlot:

@Test fun givenMock_whenCapturingParamValue_thenProperValueShouldBeCaptured () {// dané val service = mockk () val slot = slot () každých {service.getDataFromDb (capture (slot))} vráti „Očakávaný výstup“ //, keď service.getDataFromDb („Očakávaný parameter“) ) // potom assertEquals ("Očakávaný parameter", slot.captured)}

MutableList možno použiť na zachytenie a uloženie konkrétnych hodnôt argumentov pre všetky vyvolania metód:

@Test fun givenMock_whenCapturingParamsValues_thenProperValuesShouldBeCaptured () {// dané val service = mockk () val list = mutableListOf () každý {service.getDataFromDb (capture (list))} vráti „Očakávaný výstup“ //, keď service.getDataFromDb („Expected Param 1“ ") service.getDataFromDb (" Očakávaný Param 2 ") // potom assertEquals (2, list.size) assertEquals (" Očakávaný Param 1 ", zoznam [0]) assertEquals (" Očakávaný Param 2 ", zoznam [1])}

11. Záver

V tomto článku sme diskutovali o najdôležitejších vlastnostiach MockK. MockK je výkonná knižnica pre jazyk Kotlin a poskytuje veľa užitočných funkcií. Viac informácií o MockK nájdete v dokumentácii na webovej stránke MockK.

Ako vždy, ukážkový kód je k dispozícii opakovane na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found