Kotlin + Kodein Test Data Mocking

231ca3ad65e9b2ef1172e06ff0e9612c?s=47 Shun Hosaka
October 04, 2017

Kotlin + Kodein Test Data Mocking

Kotlin Test data mocking using to Kodelin.

231ca3ad65e9b2ef1172e06ff0e9612c?s=128

Shun Hosaka

October 04, 2017
Tweet

Transcript

  1. KodeinΛ࢖ͬͨςετσʔλ
 ΠϯδΣΫγϣϯ ϦΫϧʔτϚʔέςΟϯάύʔτφʔζ อࡔॣ 4IVO)PTBLB 1

  2. ͸͡Ίʹ w อࡔॣ ΄͔͞͠ΎΜ  w ৽ଔ̍೥໨ɺ,PUMJOྺ̏೥໨ w (JU)VC 2JJUBͳͲ3FZVSOJCMF

    w ΩοζϦʔͱ͍͏ϓϩμΫτͷ10݉ΤϯδχΞ
 ʢอҭԂ޲͚ͷαʔϏεʣ 2
  3. ࠓ೔ͷ಺༰ w ,PUMJOͰͷ%*ͷ࿩ w ςετσʔλΛ͏·͍͜ͱѻ͏ʹ͸తͳ࿩ w %*ΛΏΔ͘͸͡ΊΑ͏ͬͯ࿩ 3

  4. ςετσʔλͷۤ೰ w ಉ͡ϞσϧΛ৭ʑͳςετΫϥεͷதͰੜ੒ ͍ͯ͠Δ w ͋ͪͪؔ͜܎͕ෳࡶʹͳΔ w ςετͷύλʔϯʹΑ໊ͬͯલΛ෇͚ͯ΋؅ ཧ͕ͮ͠Β͍ 4

    ʼςετσʔλΛ%*͢Ε͹͍͍ͷͰ͸ʁ
  5. ,PUMJOͰ%* w %BHHFS w ,PEFJO w 5PPUIQJDLT w (VJDF w

    5 ˒
  6. ,PEFJO w %FMFHBUFTϓϩύςΟΛ࢖༻ͨ͠७,PUMJO੡ͷ%* ϥΠϒϥϦ w ˒ w υΩϡϝϯτॆ࣮ͯ͠Δ w IUUQTTBMPNPOCSZTHJUIVCJP,PEFJO

    6 Painless Kotlin Dependency Injection
  7. ,PEFJOجຊతͳ࢖͍ํ 7 ,PEFJOΠϯελϯεΛ࡞ΓɺͦͷϒϩοΫ಺ͰΠϯδΣΫτ͍ͨ͠ΦϒδΣΫτΛCJOE͢Δɻ ͋ͱ͸ɺड͚औΓ͍ͨଆͰ,PEFJOͷΠϯελϯε͔ΒCJOE͞Εͨ΋ͷΛड͚औΔ // Materials class Bean // Coffee

    abstract class Coffee(val bean: Bean) class BlackCoffee(bean: Bean) : Coffee(bean) val kodein = Kodein { bind<Bean>() with provider { Bean() } bind<Coffee>() with provider { BlackCoffee(instance()) } } // ܕ͔ΒmoduleͷதͰద౰ͳ΋ͷΛΠϯδΣΫτͯ͘͠ΕΔ val coffee: Coffee = kodein.instance()
  8. ,PEFJOͦͷଞͷ࢖͍ํ 8 %BHHFSͳͲͱಉ༷ʹෳ਺ͷΠϯελϯεͷੜ੒ํ๏͕,PEFJOʹ͸༻ҙ͞Ε͍ͯ·͢ɻ // Materials data class Bean(val farm: String)

    class Sugar val kodein = Kodein { // γϯάϧτϯ bind<Sugar>() with singleton { Sugar() } // ఆ਺ constant("Farm") with "ίϩϯϏΞ" // λά෇͖ bind<Bean>("ίϩϯϏΞ") with provider { Bean("ίϩϯϏΞ") } // Ҿ਺͋Γ bind<Bean>() with factory { farm: String -> Bean(farm) } }
  9. ,PEFJONPEVMFԽ 9 val beanModule = Kodein.module { constant("Farm") with "ίϩϯϏΞ"

    bind<Bean>() with provider { Bean(instance("Farm")) } } val potModule = Kodein.module { bind<Milk>() with provider { Milk() } bind<Sugar>() with provider { Sugar() } } class CafeAuLait( bean: Bean, val sugar: Sugar?, val milk: Milk ) : Coffee(bean) val kodein: Kodein = Kodein { import(beanModule, allowOverride = true) import(potModule) 
 bind<Bean>(overrides = true) with provider { Bean("ΤνΦϐΞ") } bind<Coffee>() with provider { CafeAuLait(instance(), instance(), instance()) } }
  10. ,PEFJOར఺ w ࢖͏ͷ͕؆୯ w "15Ͱ͸ͳ͍ͷͰϏϧυ͕஗͘ͳΒͳ͍ w υΩϡϝϯτ͕๛෋ w GBDUPSZ΍ɺPWFSSJEFͳͲ͕Ͱ͖Δ w

    $POUFYUͳͲͷΠϯδΣΫτ༻ʹɺ"OESPJE αϙʔτ΋͋Δ 10
  11. ςετσʔλͷΠϯδΣΫγϣϯ 11 ,PEFJO .PEVMF ,PEFJO 5FTUDBTF

  12. ςετσʔλͷΠϯδΣΫγϣϯ 12 ςετσʔλΛ͜Μͳײ͡ʹΠϯδΣΫτ͠·͢ɻ val factory: Kodein = Kodein { import(errorFactory)

    import(articleFactory) import(articleSourceFactory) } @Test fun testOnCreateSuccess() = given { val responseFactory: (Int) -> List<ArticleSource> = factory.instance() val response = responseFactory(10) Want(Single.just(response)).When(newsRepository).getSources() it.onCreate() val testObserver = sceneDataHolder.sourceList.asObservable().test() testObserver.awaitTerminalEvent() testObserver .assertNoErrors() .assertValue { it == response } }
  13. 'BDUPSZଆϞοΫ 13 /** * Create Article */ val articleFactory =

    Kodein.Module { bind<Date>("now") with provider { Date() } bind<List<Article>>() with factory { size: Int -> (0 until size).map { instance<Article>() } } bind<Article>() with provider { Article( title = "Samsung tried to spin the Note 7 disaster", description = "From time to time, Samsung strikes...", author = "Brian Heater", url = "https://example.com/2017/08/24/", urlToImage = "https://example.com/image.png", publishedAt = instance("now") ) } } ࣌ؒͳͲɺPWFSSJEFͰ͖ΔΑ͏ʹ͓ͯ͘͠
  14. 'BDUPSZଆFSSPSͷྫ 14 /** * Api Error Factory */ val errorFactory

    = Kodein.Module { // Domain Error(εςʔλείʔυʹԠͨ͡ΤϥʔΛฦͨ͠Γ) bind<DomainError.Api>() with factory { statusCode: Int -> DomainError.Api(statusCode) } bind<DomainError.Network>() with provider { DomainError.Network } bind<DomainError.Unknown>() with provider { DomainError.Unknown(RuntimeException("mocked exception.")) } // Retrofit Api Error bind<HttpException>("UnAuthorized") with provider { HttpException(Response.error<Any>(401, Mockito.mock(ResponseBody::class.java))) } bind<HttpException>("NotFound") with provider { HttpException(Response.error<Any>(404, Mockito.mock(ResponseBody::class.java))) } }
  15. ϙΠϯτ w ΦϒδΣΫτͷґଘؔ܎Λ؆୯ʹѻ͑Δʂ w ,PEFJOΠϯελϯεͷ࡞੒ҐஔΛ޻෉͢Ε͹ έʔε͝ͱͷPWFSSJEFͳͲ΋Ͱ͖Δʂ w Ϋϥε͝ͱʹΦʔόʔϥΠυ͢ΔՄೳੑ͕͋Δ ΋ͷɺϢʔβʔͳͲ͸UBHͰ໊લΛ෇͚ΒΕΔ w

    ઃఆ͸΄ͱΜͲඞཁͳ͍ͷͰɺUFTU͚ͩͰ͙͢ ʹѻ͑Δ 15
  16. ͍͞͝ʹ w ,PEFJOͰɺ·ͣ͸؆୯ʹ%*ʹ׳Ε·͠ΐ͏ʂ w ຊ൪Ͱͷ࢖༻͕ා͍ͱ͍͏ਓ΋·ͣ͸ςετ Ͱܰ͘ೖΕͯΈ·͠ΐ͏ʂ 16

  17. ιʔείʔυ 17 w ,PUMJO w ,PEFJO "OLP "OESPJE"SDIJUFDUVSF$PNQPOFOUT IUUQTHJUIVCDPN3FZVSOJCMFLPUMJOTBNQMFOFXTBQQ

  18. 1MFBTFKPJOUPNZUFBN 18