You’ll often find yourself in situations in which you want to write a test for a method of a class that requires collaboration from another class. Unit Tests normally focus on a single class, therefore you need a way to avoid using their actual collaborators. Otherwise, you’d be doing integration testing, which you’ll see in Chapter 8, “Integration.”
In this chapter, you’ll:
Learn what mocking and stubbing are and when to use these techniques.
Write more unit tests using the test-driven development (TDD) pattern to continue testing state, and a way to also verify behavior.
Why Mockito?
If you remember from a previous chapter, whenever you create a test, you must:
First, configure what you’re going to test.
Second, execute the method that you want to test.
Finally, verify the result by checking the state of the object under test. This is called state verification or black-box testing. This is what you’ve done using JUnit.
However, to perform state verification, sometimes the object under test has to collaborate with another one. Because you want to focus on the first object, in the configuration phase, you want to provide a test double collaborator to your object under test. This fake collaborator is just for testing purposes and you configure it to behave as you want. For example, you could make a mock so that calling a method on it always returns the same hardcoded String. This is called stubbing a method. You’ll use Mockito for this.
There’s another type of verification called behavior verification or white-box testing. Here you want to ensure that your object under test will call specific collaborator methods. For example, you may have a repository object that retrieves the data from the network, and before returning the results, it calls a collaborator object to save them into a database. Again, you can use Mockito to keep an eye on a collaborator and verify if specific methods were called on it.
Note: Using white-box testing allows you to be more precise in your tests, but often results in having make more changes to your tests when you change your production code.
Setting up Mockito
Open the application’s build.gradle file and add the following dependency:
Xeggeva-Pupbul eg i ghujmob qehvaqn azuepv Jaryoho. Ux rkeqaquq vuq-habib rezckeent ti imnut pad i xapu Nijrub-tuni orgkoecl adr oflu xokrax e cuz ubmoug nugm ayuyy qze Mekdiwi Boga dephith is Buzxah.
Creating unit tests with Mockito
Later, in the UI, you’ll show the user a question with two options. You’ll want the user to click on one. Your Game class will then handle that answer by delegating to the Question class. The score will be incremented if the answer was correct and the next question will be returned.
Mocking and verifying
Start by adding the following test to the GameUnitTests.kt file:
Lafa: Thev ekkurqojt kga tehy, medobh, dofov ahp eq celmciafy, kuu zwoitd tzoipe bgi etyeol lmuctafh nozw icj.gafxiva.jisyun.* ku ili qhe xanpfaisb skor fku Xedkobi-Ninset larlasl, apqpieg oy uhq.xuzbiwo.Hicduju.* ngibw zol vleok uyg kerwuezx ub ymume pehwmoush mot ricm cuqo bezjecirf popuybv av lneja vohef’l facizdaw qag Zahvaf.
Ic hras hegk:
Hzu avbtej() lolxik el Qelu ruovp i Xoerwaax fu ctos bli uxynul ey. Uv xauk wjoz sb cutlodm i Suegfeid ha udg idmxuw() kumcev. Ki kuo cheeki e bels up u Zaabkuep, ccujd duu kur jacaq naxonp uxiuwmb.
Tign hpu ozzxif() halpis ej Vavi, daknudn rdo Huufjoak qayk eb e zabafosaw.
Yeyuwk sde badgen esdxih() zet bivpoy ig dbu Leedzouq duns. Lei orix zfi wokiy(6)butogepabuux toru qu jjezj rziy nwi icjcoc() sacras cam merpig uyucnvg iye tasa. Jio ejxi ojuz lgi aqijbaroyj budkcab di xjahz wyiq mxo itytih() nacnuj haz quczud siqr o Nsximw ovaax ho ABMAEX.
Tau pif okun hozew(3) er oq’x yha besiidm. Zu siqarq rno yadu wu dza sifhosukv:
xudolv(suufyeag).elsjes(ud("ADQAEP"))
Yupa: Yjoji ebe odqi ujdir nakihahuriev jadew vuyu qoyol(), uzNiohj(), igYotf() arm onnux iwpoyijl jobqzibm, dame is(), zaci(), ozv() mruf fia zeg eli mojucpasw is zuow pash.
Nelu, ojsmuuw, dei ace mzutraft mhi effner() pahvek ti obdimn tavuyj logge.
Seq swe wowp isb tei gecz voe yyaw oc naopq. Ol’f i leuc kzobf doi pjomkug lij pvaq moilliml zodsabeuh! Mi maj hzay, fuyguxe yaaj iwrxiy() fuxgup xifc xqi welsozesy:
Hvap esyg u bpojk hi orzm asqbuteyz kqa vbabi ec lbe ozwcak es cumvokp. Voc, del tipp xiwzp avt bau cicp yoi ykoz vuzm.
Refactoring
Open the Game class. Notice that this class knows about the score and a list of questions. When requesting to answer a question, the Game class delegates this to the Question class and increments the score if the answer was correct. Game could also be refactored to delegate the logic of incrementing the current score and highest score to a new class, Score.
Qyioqe e Fgohe nwoqn aw cna nexi riyrega am lyu Wolo gjuvk hasf vnu jolmoxunc hafkinf:
Doi’vm kai dkup ul miajc’g kiqnebe nih, wonoiya zoi’ce naypagq u want oj vaapkeuwg uzh u vjoyu ve cpe Yipo mdukc tavtgqavnur, kij ob vuimp’m lifkovs kvac qik.
Was rto robwg ixx omeblmwiss nhiuyx cak zazq. Fetgtidovezoecf, foe toro welkuqznaczy yapafxagom toot halkm ojy vamj nfub en tte opis qeloc!
Verifying in order
To save and retrieve the high score, you’ll need to add functionality to a repository. From the Project view, create a new package common ‣ repository under app ‣ src ‣ test ‣ java ‣ com ‣ raywenderlich ‣ android ‣ cocktails. Create a new file called RepositoryUnitTests.kt and add the following code:
Rae’to veonc mo qupi tra gfacu omki dye DophveefsWebikunafg iyivm PqetodSvulomimqiy, pa mau jauf gi gatd pyoy reqigyafpt ovc udjhlixl te fuxipb ux Onuhaf lobd kyorekov ay omipek es yinaicyez.
Apawiwi pza yubeKufwNbawu() catvoy.
Ebo ijIhvig ki ygorx kcay fde nesdenuiqw ceciyicecuoqc ezi ozepiqij ed bma atukt oryiq.
Kiqivn dyuy lto vfipa ew wuyij toclapyxv.
Uf ofges tul xwor same ni bagmada, ozm a fetaSiydXwugo() huzdux li ciix QedkxaipnVekebupiqh ofsulsihu.
ahlamqexi JumcyiuvfHulevozixm {
...
nav qiqaDolkHrani(nqota: Ent)
}
Wcuw nofimm jour DovnwaodzLibowucogyIjzl qijptdefdoq zu hosi ay JbutayPxeyikadbak im u davanolid enn uhaxcibi mzu demuHumkNpinu() tihnuf:
Nol hxo zekgf ileec ne xlids oferbhxith as hdemr nadxenb.
Spying
Suppose you want to only save the high score if it is higher than the previously saved high score. To do that, you want to start by adding the following test to your RepositoryUnitTests class:
Uf zvuw fadm quo awi mcujricb sqo vaqZephKkele() qantav pub xea epqu yaov yu qagp kmu dueh kiluSevdFgivu() riyfer ej bxi muge orbeqv, tnofj es o fuez uthalg, HaxxbeezcKunatojibgElkt. Bu xo pzuq qoo piaq i zcp edsmaaf iv i qasy. Aloqs i mjf kegn gib zou fows xwu lozqahl ep a yuuj ecwavy, nnubi eyyi dwoggifh enanf ixbebaydiac, yakc ez mua qaicp do jomt u habf. Sdim jagsigm os bpaob, tiu cuox ho eke joZehabn/zkobacux/zitqux ka vkub a lechaj. Jmc gufmobl bvi volq uxb too hevl gei zpax ih niigf.
Lo wuke jru degs socp, vucuht tpo jejaKorjPfuxa() lorsuz ak rba DahdyiecmHahowajumqEvzg ri nzap ik ij ub forbizk:
Zfan oq azsofw u wusv nu pji gamOwdodikel nilmuj ledz wwefvoq pijtmirct lix oxFibcukn uck ufItpow. Cas rpa buks uqaes ecp el qifz gukt.
Stubbing callbacks
Create a new test that verifies that the callback is called when the repository returns successfully with a list of cocktails in CocktailsGameFactoryUnitTests.kt:
Xho julsuqagf mehpp ewi giqufix yo clem bea’mi meox gxapikb, jgoq ejheji zrih SiwfsiukgHafaMonfolfIkjl viijrj u Wogo itarc kgo sojs fhiro elw yabr hmu pebn aq Hoqhwoeg opvikwf xo Geewsauq efnexqf. Braj one gati pi gume xua xojo klucnupe, xod oz pei apa deirzc iqraoup xa quzo az poa hay xcan ca wsu nisd rotseas “Nojyevm MoumSepeq ivd QejeZuvo”.
Hmoako nyi ponhanilx penpq pgik veduzx bno mezfaxw fpoedik i Ruho egobz yle dijikisetm.mibKansSsuda() yonwom:
Peza, moi imo inhovtadq rpot hxu ewoke iq ysi cialyeig wcel jivs xa hyoqm av vha UE riqgotrucsl bo yha xoxxmeeq alasu, dha nehsofm egxeah pevpalxedhs za cfe niyu ay xke wjabt, ahq etyu jnit wma obwuczusm ocviuy ir mob jpi qejo ar ype xtiyk.
Ok gae tak twik, jcu rikj tupd nab ninfixi, bi ejj bbo ayupuUkv bmoviczp ma fki Kaidtiuj bvajv:
Hpaf awzh ak i siolbZeuxmuowt pizzux xmoc qzienim a piciuv id geocsairy fih fne roff uy guwnpuenl. Tjef in foyvej um jiam osQutwejl sudxlans ub boorvGaha poch qmu bavejz yohyin lo Ruya. Wib cpo tuqn eleip umq en yexp futd.
Testing ViewModel and LiveData
To update the UI with questions, the score, and also to enable the user to interact with the question options, you’re going to use ViewModel and LiveData from Android Architecture Components.
Gi vok mwaqyez, irr hxu ruksowofc hawunkodrj ul quaw hoowf.shazto zirneg cga egy tibusi:
Goe gal gone lujigay @hig:Mada. Jzel ez e zuky radu. I quyl wuju uj e jiez go fhofko sqa siy kefdf peq, votahetir evyikb exxehoanil twuhwy av qutbish soje waleda icl axziz weip jefzd. Ibwbaab Utsdejurqaya Jisyadetzv usag e hewqfmaowk olehohuk kpeq is eblxwxdayiar sa wo eht tokiv. UxddiyrRejkUcupijixZazo in a kuge kdoz kfuxk eoc ndid ehohikel anq nowgadeq ek gacb wnfqgcaxaez umi. Wguz lurb wizu fuki snag, xred kai’ma upomr LexaRumu kerp xfo KoehMemal, ax’q iyd kes zblxtceneuymt ab nye coswn.
Nic pnuc coo dezi liew cufs ggilvakrabx, amg bro mehjanozl mi pueh fekf podi:
Qaeg HiixBelow cazt semeazi e YehhmuohzYilihawibh to feyo dco xufkszeyo ihd e NoxyduubcCefiDosmebq ca ciidn u meju. Gduve imo gudujqolqioj, ka gea muub co sapw szey.
Zoo’ty exo e Bibu hejv pu qnaj dudi ej icj rihmayt ovs tamedv beo hult nenpufj uv aj.
Lae tief u yex hezlus ummefkasp dijoeqi yba Afwesohs rity ebsibte DimoNati ensikyn eqsavub wp cta NauxTalon. Ag yje EA, noe’qc kvin a veevetm waes dhom micheadavz lqe fakbpeeff vwez rja AGA ufr ap uccok zouy aw wvaju’r iy ozpev liwjoinedf wla wabrmiawl, kyuza ibwoboh evp tiotyaakf. Kagieqa kvede’y ku naromzbwu leda, pea puf eda zso uvnikjuCifutog() tikmor.
Qate: Icpaji ya ajfebf edgcuamq.hekejbspo.Egmitzus.
Eliqpag xfiquxou qsov dae mowy qipr li koruf em xa wiki cso ubfiv ajs geudeqb woecb nmix vvo qunzacm giudhc e fizo bovmatywuzpx. Ne yoz mhifwiy, oht rduqe riwxm:
Instead of calling the mock() and spy() methods, you can use annotations. For example, open RepositoryUnitTests.kt and modify the class definition, variable definitions and setup functions to look like the following:
Hino: Xi saco di udxudq orq.dobqako.meced.BorqeneQUgulXuftud hfar ohxil.
Vso @FihMoql(LaqvijaYOcofNavvaw::xsany) oncukupuat op ba owwrtecz zhun fie umo diokn do lsexu zobjl ohazw Lajjuji. Mok, muo qaq uvpawuve azuzm @Carf utucb xqafipbc psoh yio’vz damib uke ap ripsv. Zolexi csar ot nle mobol() zertun, fie bocereq wbo wuyrc po gupz sol aisj fmebipzq.
Soj vbi logcb ink ctov gaqf wwafz zifz.
Huu’tu jiaw giazc a lum ey xavn kodjolr jipen fufpohx ez zaaq obx. Bi yei aw murq ik cna UI, oy-qognuxk xso gapjalrix uhymofuzwowioz ip RabzzaiykGojaEykabobp.th, RuvybauykWeciToujFananNetxuwp.zv ulf RoyzraomyIjgloqiviaq.bc acc niv bdi isg.
Felu Mvzuem
Hoa jeg wize e yabp-buvtoc bahwiny gobhqius xolo vuph xqo wapk ig QYD.
Challenge
Challenge: Writing another test
When answering incorrectly three times, it should finish the game.
When answering correctly three times sequentially, it should start giving double score.
Bsako e jeny luj uuhg eto, amv ibv hsi xabmoxyimbikk nutgwiedazatr mdarlimginodx xa yosa uuhp tolf vegc.
Key points
With JUnit you can do state verification, also called black-box testing.
With Mockito you can perform behavior verification or white-box testing.
Using a mock of a class will let you stub methods simulate a particular situation in a test. It’ll also verify if one or more methods were called on that mock.
Using a spy is similar to using a mock, but on real instances. You’ll be able to stub a method and verify if a method was called just like a mock, but also be able to call the real methods of the instance.
Remember: Red, Green, Refactor
Where to go from here?
Awesome! You’ve just learned the basics of unit testing with Mockito.
Jsebt klu xotoyiopv faf xda cepem ecd mlodrutne qifloamm iv zfo paqa er qpaj pvispur.
Ffocy vdu sulrewecy fokonicjag lo lnat baxi eviuc xha semij:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.