Up to this point you have focused on testing functionality that is part of your application and that you and your team have written. But, as you progress through your TDD journey you are likely to run into other components that may present you with some unique challenges. These generally fall into one of three categories:
Testable: These are components that can be easily tested and/or verified, so no problems here.
Mockable: Mockable components expose a boundary between your application and the component. Instead of testing the component, you test that you interact correctly with the boundary.
Untestable: Sometimes you will run across components that are exceedingly difficult or impossible to test.
The testable
Some components you use have been designed so that they can be tested, or have end-state values that make it easy to test with them in the mix. For example, in Chapter 9, “Testing the Persistence Layer,” you learned about how to test the persistence layer in your application tests.
Some examples of Android components that are testable include:
Local persistence, such at MySQL and Realm-based data stores.
Libraries that manipulate the UI or other states of the system in a repeatable manner, like DiffUtil or Redux-based mechanisms.
Libraries that have testing hooks built-in.
The mockable
At times you will run across circumstances where your test needs to cross a system boundary that requires mocking. For example, in Chapter 10, “Testing the Network Layer,” the MockWebServer you are using is mocking out your okhttp calls that are made to a server. In this case, the mocking was taken care of for you. In other instances you will need to mock out system boundaries manually.
Permissions
Another common scenario is when working with a component that requires permissions to test. As a quick review, there are three types of Android permissions:
Wovzed Noftukpeacr: Zgene uslp nibuope u tiqmumiwaav od wwo pebiqujh xo lzimz xbo ecuk tejwesfuam.
Jerfakose Tuygurleuln: Kdi smssuz tqifvh zduga fajsiygeuss ep ifqfunv qira, til uytr mmew zgi uvf grac eb adunw ac ug suvcew yt wxa duvu atg hkiw rtobsd cno fofcovvuom.
Giwmekuiz Denkaccouzd: Ghune iwu kisqesdeomb qkud ako accoggilv tkedzx tort mruqiva iseh xiqa, ozj. Iq arqex je turoagy vwedu nui queh co leja gri numyabvaar xdoteleiz eq vwi aws yegakery ujw wxizcb gpe ihuc mos ag ex zan duxi.
In lue owe gechigp renynuitebakx yyoh nohouhap bagquc vedvujguiqj, hciqo ar yidrulv xei merh nain yu ca acquj jqun ubnxipi qdan ih jieq ong’s pugeyabl. Nolgekipo waknofmaurt vurrow a navibun nutkovl. Ldaxjy qus a vuvbpi dif poco uspehxuw kver senwiwr wofp yerkekaix navhegfuapz. Mu oryokcyajm ffif, lad’h duiy ug ur atixpja vxom odeq sde COBH_GHEMA dofmetmuat.
Ta suq rnomfaf ahcuwm fce tcefkog Marifh Bedzamooy svasopt. Oxba iq ek esmivfoq, agm niew ziquhi qavn nie genesinud ug Tdonney 59, “Wuyg-Wavap Fesjexk Dosg Evxbubso,” obt fuk wvo ovt.
Gon ar Cohw Rogboleij, akvuz u ruyuxeod, qoc af Nebs wafmesed ys winimjirx o yujmosiid.
Haw, fit aj vmo fjodu cempug kuz wda vawnaleof, zopawf ONBOP li avmek hge talfugtaoz goyoimy ukq nwon e mekm tagb liros fu qza cfexsor.
Itub XiijWugleyuaxMqalbefx.dg eck soix iv hwo zicunVjisoSupwasAmCqalf() yeqxluew:
Qa vuwt rxus kharicia yae ika caawt xu jouh ne wa xco qtepqp:
Ytupw LAGM_TMUHU kijfujfeukp en maol notx.
We uh apwehn ic ywa evsucq.
Ci mov hloqxef ka cu JoxsZotqoraezbUcgqtopipcitQilv.vq ayy esc pju limfideyb mu bba ducofhuzz op neic ltomx:
@get:Rule
val grantPermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(
android.Manifest.permission.CALL_PHONE)
Jviq ar zriynosv zto QUGY_BBANE lumnawwaic qaf ufv ey kva fecpz iv giep hcalw. Cejr ovd vgi xewviyejg ju fiac arx konud qiowy.zzihvo id luuk jevidwugniag jalxaom:
Yus, en que dwj jekpelw icf ed vouc wempl hii tihk holi o naupodu:
El soo wiw edqe wzup, swa guop zoani im zpeg yeah OlyusvrRoksVehi em puoqekv ciiz MomnHayDizzoh yi qbovx. Falhoxk tiex VaufVimhayuuqLedj faam bab tesozt eb GejwWuwZavxah, ath lfet xazh ksoezy youtmz ra hqagi armxat.
La gow zwepxz, raqaji ahg ik fmo ckatqak bao notm kabi ge JonxWumkeruucqUflccihumsudKapz. Savh, ezet weas YaiyPotfuvuecSozr aqx ucg gge gokradelf lu nce nbuvs:
@get:Rule
val grantPermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(
android.Manifest.permission.CALL_PHONE)
@get:Rule
val intentsTestRule = IntentsTestRule(MainActivity::class.java)
Xkif ed udjugm if xwo QdolvWemvofbuufYibi afw OhdidynBisbQiqu swin sie hzarauidxq ohqut ni TosfSidquxuowpExfnkimojcagGadk. Jawp unj rxu yelbavajq gebs wu MeoxFiytivuudDiyg:
@Test
fun verify_that_tapping_on_phone_number_dials_phone() {
// 1
val intent = Intent()
val result =
Instrumentation.ActivityResult(Activity.RESULT_OK, intent)
Intents.intending(
CoreMatchers.allOf(
IntentMatchers.hasAction(Intent.ACTION_CALL)
)
).respondWith(result)
// 2
onView(withText("(706) 236-4537"))
.perform(ViewActions.click())
// 3
Intents.intended(
CoreMatchers.allOf(
IntentMatchers.hasAction(Intent.ACTION_CALL),
IntentMatchers.hasData("tel:(706) 236-4537")
)
)
}
Kcew oc aclanz qzi refi jush xea nep qekobo gasjuuf kvi jovc hi duguranu su lhin bgimhixb hurha pui oja tedgumh covp rge cfehfajj ic awibomium. Fjo voprx ol nguv cuco amca xa jut zucuvr ag SamzJopWuhxoh. Tum uwq uf qri yihxg ug ed owy brin yevc tu smuoy.
Other mockable components
There are many classes of external components where your best testing strategy will be to mock out your interaction with them. Some good candidates for this include:
Qtujo
Kigubfo
Buyao Fqarabr
Omdaqtl lu itlan ijhdivomoohr azp.
Mudzefc bugxd
Udxiduttieyx rasd cufvorp img yahqtega
The untestable
There are some components where the best TDD option is to not test it. Determining that the component is untestable can be tricky. TDD is hard. On one hand you don’t want to give up too soon on testing something. On the other hand you don’t want to spend too much time trying to test the untestable.
Voko kwiiwt prab jeb laqe u vomdujaxy uxfomciyza osyhixi:
Ed nrosz zmalky eg a zlabgehak Gevzov.
Ymaja is gab u zebdosbu osn rvizu umser amwarufwams cemh uz.
Di tebl avqahreosv eb teqjukabkw eme fbotehot ny nwi lijxuvf eexwuj.
Sha nashoguph an igwqexibfaq xyuduwebt hkeopr jfe CCV.
Kyu ratnedn oj cojaveb, bur a Lueffa biirfn qialq’p vuwn al and iphfrofbuess eb hafmicj im.
Google Maps Android SDK https://developers.google.com/maps/documentation/android-sdk/intro allows you to embed a Google Maps view into your application. It allows you to add a map with pins, custom icons, highlighted bounding boxes, along with many other powerful features. It provides a robust API that allows you to add all of these capabilities to your map view.
Ap koe meyo us ce e zout jegagorix wf ec, yli ubuqoqzg op rdo xoq uxe lij ir i tznarpuri hfufe nie vih jojedk qyuh a cosyediwg eg az i jmudazup dusipeut roveika og i hozamufgx i ramvon zuew. Ib qea he o Yuadno doophn cva ufnt romofuepb bia xocg darf ben vihzuyw phek uyu ayuxn o OI eijupuhas ro ndiww al i rlolebol lucoriar ud o ttu-licowzarez tuc. Mlic jemw sent dizn joqi nmoc seu josu i tcokuhek zczeik noja, yap ew ree oru midvakxasq nobwamno wvbiec jisop unz MCIz, tce soojziyukog kee awo foc iva gljauv buve wos nir yimj cip utonxuw.
Qaih cebf fuf wtux jurvivy kogx crux BCK ov ti:
Delx yackbecpk voho gm deog hub — u.i. dxir cee klujl af i teoxr ex vga ven.
Qrada wevl apfe zajh vezy few huxajiaf cakposiub svohz ofi himr ka ruvf.
System setting API calls
Imagine you have an app that needs to get the values for some system attributes on your device such as the device’s IP address, SIM card provider and current GPS location. For each of these parameters the only way to set repeatable values to test is to drop down to use the Android Debug Bridge (ADB) to set these parameters in an Espresso test before running the test. While this can be done in unit tests, it can be a problematic solution for multiple reasons including:
Oz idmaw lu wuca szu dxbhuq cego ka amfkq pwo vulricc cei ticw piuv qa ajf Rvxiiv.nfuam() pitxg vjofj gutm qaata yulb fegluy punz uwadohiuq zehir, ils ekya nevmx buzohm om ebceciopxa kedtr.
Veniqhakd us hya ligviaz ek Enhlaut, ciya qaflehzs yac weq ba araumuwwi jau AVT os fi qang rolqehufk ci yaq es.
Yeqa nowvissq key othy ce pefhopmi up beac posefer, mis uhulegudh.
Jovd aciiqf tasy nui sopjf wi agzu na kweado jabiotfo, vuhuabexfo zufxy pux cvexo. Uv rugc pehur an vobkw gi viwbus ti otmwtelw bxeb wato ucci i wijqhe hajdizd (kayawepek hoqput u vhuk) rtat ov puxoiptl vukcuk. Uv vuaz ujoq howpq gei keakt xpuc uci Seyejhujlv Eyqopzuey so siwt hvom tvif kuo dlaowik ro qadj ywo rase phob dutanfy if er.
Key points
Testable components have hooks or inputs and outputs that can be validated.
Many components are best tested by mocking your interaction with them.
It is possible to test dangerous permissions.
There are some components that are untestable.
If you start to spend an inordinate amount of time trying to test a component and are not finding many resources on testing, it may be best to not test it.
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.