Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mockk Tips / mockk-tips

moriiimo
March 27, 2019

Mockk Tips / mockk-tips

3/27のAndroid勉強会で発表した資料です
お話したことを簡単に記載します

0. Title Mockk Tips

1. 自己紹介

2. メニューズよろしくおねがいします!
健康的な献立を提案してくれるアプリです

3~8. ことの発端になったコード
・privateメソッドとしてクラス内に押し込めておきたいメソッドを使っているpublicメソッドのテストを書きたい
・メソッド内部で生成されているオブジェクトの変数のテストをしたい

9~11. mockkを使って解決しよう!

12. mockkは使いやすいです
モックオブジェクトの作成はMockitoの使用感と同じです
導入については割愛させていただきますが
公式が充実しているのですぐ使い始められます

13~14. spykを使ってmock化し、recordPrivateCallsをtrueにすることでプライベートメソッドをフックすることができるようになります

15~16. every~returnがmockitoで言うところのMockito.whenと同じです
privateメソッドは mockobject["privateMethodName"]でフックできます
returnsの後ろに任意の返却値を書きます

17~29. 評価はverifyに記載します
inverseオプションをつけるとテスト対象のメソッドが実行されていないことを確認できます。inverseの代わりにwasNot Calledを利用することもできます

20~24. slotとcapture
slotは実行されたときに作成されたオブジェクトを保持しておける枠のようなものです。every block内でcapture(slot)とすることで保持されます。
保持されたオブジェクトは評価で利用することができます

25. ありがとうございました!

moriiimo

March 27, 2019
Tweet

More Decks by moriiimo

Other Decks in Technology

Transcript

  1. ࣄͷൃ୺ 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<String, String>): Completable = getHoge() .flatMapCompletable { apiClient.send( ParameterJson( time = System.currentTimeMillis(), hogeId = it, appName = "ϝχϡʔζ" ) ) }.subscribeOn(ioScheduler) private fun getHoge(): Maybe<String> = Maybe.create { emitter -> try { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } } }
  2. ࣄͷൃ୺ private fun getHogeId(): Maybe<String> = Maybe.create { emitter ->

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

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

    { val hoge = Hoge.getHoge(application) emitter.onSuccess(hoge.id) } catch (e: Exception) { emitter.onError(e) } } ࣄͷൃ୺ આ໌͢Δؾ͋Δͷ͔ʁ
  5. ࣄͷൃ୺ override fun sendEvent(extras: Map<String, String>): Completable = getHoge() .flatMapCompletable

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

    apiClient.send( ParameterJson( time = System.currentTimeMillis(), hogeId = “hogeId: “ + it, appName = “ϝχϡʔζ" ) ) }.subscribeOn(ioScheduler) ࣄͷൃ୺
  7. લ४උ val application: Application by lazy { mockk<Application>() } val

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

    ApiClient = mockk() val mock = spyk( objToCopy = SenderImpl( application, apiClient, Schedulers.trampoline() ), recordPrivateCalls = true ) લ४උ val mock = spyk<SenderImpl>() ܕࢦఆ΋Մ
  9. ςετ given("Hogeͷऔಘʹࣦഊ") { val throwable = Exception() beforeGroup { every

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

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

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

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

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

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

    mock["getHogeId"]() } returns Maybe.just(RandomHelper.randomString()) every { apiClient.sendEvent(capture(parameterJson)) } returns Completable.complete() } } ςετ
  16. given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot<ParameterJson>() 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()) } } } } ςετ
  17. ςετ given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot<ParameterJson>() 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) } } }
  18. ςετ given("Hogeͷऔಘʹ੒ޭ") { val parameterJson = slot<ParameterJson>() 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) } } }