Slide 1

Slide 1 text

.PDLLUJQT "ZBLP.PSJNPUP!NPSJJJNP

Slide 2

Slide 2 text

"ZBLP.PSJNPUP %..DPNMJGFࣄۀ෦ ࣗݾ঺հ %SPJE,BJHJΩϯνϣʔ͠·ͨ͠

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

ࣄͷൃ୺ internal class SenderImpl @Inject constructor( private val application: Application, private val apiClient: ApiClient, @Named("io") private val ioScheduler: Scheduler ) : Sender { override fun sendEvent(extras: Map): Completable = getHoge() .flatMapCompletable { apiClient.send( ParameterJson( time = System.currentTimeMillis(), hogeId = it, appName = "ϝχϡʔζ" ) ) }.subscribeOn(ioScheduler) private fun getHoge(): Maybe = Maybe.create { emitter -> try { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } } }

Slide 5

Slide 5 text

ࣄͷൃ୺ private fun getHogeId(): Maybe = Maybe.create { emitter -> try { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } }

Slide 6

Slide 6 text

ࣄͷൃ୺ private fun getHogeId(): Maybe = Maybe.create { emitter -> try { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } } આ໌͢Δؾ͋Δͷ͔ʁ

Slide 7

Slide 7 text

private fun getHogeId(): Maybe = Maybe.create { emitter -> try { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } } ࣄͷൃ୺ આ໌͢Δؾ͋Δͷ͔ʁ

Slide 8

Slide 8 text

ࣄͷൃ୺ override fun sendEvent(extras: Map): Completable = getHoge() .flatMapCompletable { apiClient.send( ParameterJson( time = System.currentTimeMillis(), hogeId = it, appName = "ϝχϡʔζ" ) ) }.subscribeOn(ioScheduler)

Slide 9

Slide 9 text

override fun sendEvent(extras: Map): Completable = getHoge() .flatMapCompletable { apiClient.send( ParameterJson( time = System.currentTimeMillis(), hogeId = “hogeId: “ + it, appName = “ϝχϡʔζ" ) ) }.subscribeOn(ioScheduler) ࣄͷൃ୺

Slide 10

Slide 10 text

NPDLL࢖͏͔ʔ

Slide 11

Slide 11 text

QSJWBUFϝιουΛNPDL͢Δ ΦϒδΣΫτΛΩϟϓνϟ͢Δ NPDLJUPͱͷ͔Δʙ͍ൺֱ ͜Ε͔Β͓࿩͢Δ͜ͱ

Slide 12

Slide 12 text

લ४උ val application: Application by lazy { mockk() } val apiClient: ApiClient = mockk()

Slide 13

Slide 13 text

લ४උ val application: Application by lazy { mockk() } val apiClient: ApiClient = mockk() val mock = spyk( objToCopy = SenderImpl( application, apiClient, Schedulers.trampoline() ), recordPrivateCalls = true )

Slide 14

Slide 14 text

val application: Application by lazy { mockk() } val apiClient: ApiClient = mockk() val mock = spyk( objToCopy = SenderImpl( application, apiClient, Schedulers.trampoline() ), recordPrivateCalls = true ) લ४උ val mock = spyk() ܕࢦఆ΋Մ

Slide 15

Slide 15 text

ςετ given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every { mock[“getHogeId"]() } returns Maybe.error(throwable) } }

Slide 16

Slide 16 text

given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every { mock[“getHogeId"]() } returns Maybe.error(throwable) } } ςετ Mockito.`when`(mock.getHogeId()) .thenReturn(Maybe.error(throwable))

Slide 17

Slide 17 text

ςετ given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every { mock["getHogeId"]() } returns Maybe.error(throwable) } } on("ૹ৴ॲཧΛ࣮ߦ") { val result = mock.sendEvent(extras) it("ૹ৴API͕࣮ߦ͞Εͳ͍") { result.test().await().assertError(throwable) verify(inverse = true) { audienceOneApiClient.sendEvent(any()) } } }

Slide 18

Slide 18 text

given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every { mock["getHogeId"]() } returns Maybe.error(throwable) } } on("ૹ৴ॲཧΛ࣮ߦ") { val result = mock.sendEvent(extras) it("ૹ৴API͕࣮ߦ͞Εͳ͍") { result.test().await().assertError(throwable) verify(inverse = true) { audienceOneApiClient.sendEvent(any()) } } } ςετ

Slide 19

Slide 19 text

given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every { mock["getHogeId"]() } returns Maybe.error(throwable) } } on("ૹ৴ॲཧΛ࣮ߦ") { val result = mock.sendEvent(extras) it("ૹ৴API͕࣮ߦ͞Εͳ͍") { result.test().await().assertError(throwable) verify { audienceOneApiClient.sendEvent(any()) wasNot Called } } } ςετ

Slide 20

Slide 20 text

ςετ given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot() beforeGroup { every { mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } returns Completable.complete() } }

Slide 21

Slide 21 text

given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot() beforeGroup { every { mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } returns Completable.complete() } } ςετ

Slide 22

Slide 22 text

given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot() beforeGroup { every { mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } answers { if (parameterJson.captured.xxx) { Completable.complete() } else { Completable.error(Exception()) } } } } ςετ

Slide 23

Slide 23 text

ςετ given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot() beforeGroup { every { mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } returns Completable.complete() } } on("ϩάΠϕϯτૹ৴ॲཧΛ࣮ߦ") { val result = mock.sendEvent(extras) it("ϩάΠϕϯτૹ৴API͕࣮ߦ͞ΕΔ") { result.test().await().assertComplete() verify { adApiClient.sendEvent(parameterJson.captured) } } }

Slide 24

Slide 24 text

ςετ given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot() beforeGroup { every { mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } returns Completable.complete() } } on("ϩάΠϕϯτૹ৴ॲཧΛ࣮ߦ") { val result = mock.sendEvent(extras) it("ϩάΠϕϯτૹ৴API͕࣮ߦ͞ΕΔ") { result.test().await().assertComplete() verify { adApiClient.sendEvent(parameterJson.captured) } } }

Slide 25

Slide 25 text

)BWFBOJDFNPDLL ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ