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

::class.fixture() pattern — 拡張関数を生かした、Test Fix...

::class.fixture() pattern — 拡張関数を生かした、Test Fixture 管理の紹介

* “Test Fixture” とは、 Unit Test 等(以下単に Test)で多用される前提条件やインスタンスの集合体を具体的な Test Case とは別けて管理したものです
Test を明瞭で読みやすくする(そして書きやすくする)効果があります。
* Fixture は再利用する事が可能で、定数として定義して参照する等の方法があります。 定義箇所や方法によって見つけるのが難しかったり、再利用箇所が限られるといった問題がありました。
* そこで、クラス(KClass)に対する拡張関数として Fixture を定義する事で、Production コードの汚染を避けたままで、IDE による補完の恩恵を受けられる管理ができるようになりました。
* これについて、記述方法を元に ::class.fixture() pattern と呼んでいます。
* 本セッションでは、Fixture の概要から始まって、::class.fixture() pattern の具体的な記述方法や、IDE で補完される場合の体験を、デモを交えながら紹介させて頂こうと思っています。

2022-12-10, @ Kotlin Fest 2022

Avatar for Kazuki MATSUDA / 松田一樹

Kazuki MATSUDA / 松田一樹

December 10, 2022
Tweet

More Decks by Kazuki MATSUDA / 松田一樹

Other Decks in Programming

Transcript

  1. セッション概要 ¡ l5FTU'JYUVSFzͱ͸ɺ 6OJU5FTU౳ʢҎԼ୯ʹ 5FTUʣͰଟ༻͞ΕΔલఏ৚݅΍Πϯελϯεͷू߹ମ Λ۩ମతͳ 5FTU$BTFͱ͸ผ͚ͯ؅ཧͨ͠΋ͷͰ͢ ¡ 5FTUΛ໌ྎͰಡΈ΍͘͢͢Δʢͦͯ͠ॻ͖΍͘͢͢ΔʣޮՌ͕͋Γ·͢ɻ ¡

    'JYUVSF͸࠶ར༻͢Δࣄ͕ՄೳͰɺఆ਺ͱͯ͠ఆٛͯ͠ࢀর͢Δ౳ͷํ๏͕͋Γ·͢ɻ ఆٛՕॴ΍ํ๏ʹΑͬͯݟ͚ͭΔͷ͕೉͔ͬͨ͠Γɺ࠶ར༻Օॴ͕ݶΒΕΔͱ͍ͬͨ໰୊͕͋Γ·ͨ͠ɻ ¡ ͦ͜ͰɺΫϥεʢ,$MBTTʣʹର͢Δ֦ுؔ਺ͱͯ͠ 'JYUVSFΛఆٛ͢ΔࣄͰɺ1SPEVDUJPOίʔυͷ ԚછΛආ͚ͨ··Ͱɺ*%&ʹΑΔิ׬ͷԸܙΛड͚ΒΕΔ؅ཧ͕Ͱ͖ΔΑ͏ʹͳΓ·ͨ͠ɻ ¡ ͜Εʹ͍ͭͯɺهड़ํ๏Λݩʹ DMBTTGJYUVSF QBUUFSOͱݺΜͰ͍·͢ɻ ¡ ຊηογϣϯͰ͸ɺ'JYUVSF ͷ֓ཁ͔Β࢝·ͬͯɺDMBTTGJYUVSF QBUUFSOͷ۩ମతͳهड़ํ๏΍ɺ *%&Ͱิ׬͞ΕΔ৔߹ͷମݧΛɺσϞΛަ͑ͳ͕Β঺հͤͯ͞௖͜͏ͱࢥ͍ͬͯ·͢ɻ
  2. ͜ͷηογϣϯͷ (PBMɾ ಛʹ͓ಧ͚͍ͨ͠ํ ͜͜Ͱ͸࿩͞ͳ͍͜ͱɾ஫ҙ఺ ¡ Goal ¡ Fixture 管理重要かも、と思って頂く ¡

    Fixture を管理するのに良い方法 ¡ Gradle module 内 → ::class:fixture pattern() ¡ Gradle Multimodule → java-test-fixture plugin ¡ 特にお届けしたい方 ¡ 『Test を書く時間が足りない。。。』 『Test がなんかごちゃごちゃしてる?』 『読み返したら読みにくい・更新しにくい』 ¡ という現場あるあるを持ってらっしゃる方。 改善策の元ネタの1つに使って頂ければ幸いです ¡ ここでは話さない・話せない事 ¡ 良い Test とは ¡ 良い(Testable な)設計 ¡ 注意点 ¡ 『特定のパターンを紹介する』という形の発表には なってしまいますが、同時に現場での Fixture の扱い、 というものをまとめる事に注力しました。 ⚠ 拡張関数のご利用は計画的に! ⚠
  3. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ¡ 'JYUVSF؅ཧͷॏཁੑ ¡ 'JYUVSF؅ཧ͋Ε͜Ε

    ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH
  4. 自己紹介:松田一樹 (@kazuki_matsuda) ¡ Senior Software Engineer (Server Side) in LINE

    Digital Frontier 株式会社 ¡ = 『LINE マンガ』. ¡ 興味の1つ = 分断を避けた Scalability で、開発効率を上げること ¡ git-lfs scalability. ¡ e.g.) Implement “git-lfs dedup”. https://swet.dena.com/entry/2021/07/12/120000#:~:text=git%20lfs%20dedup ¡ 課題・動機: ¡ 当時開発していたプロジェクトのリポジトリサイズが ~ 100GB。(Asset 含む) / 複数 Checkout をしたい。hardlink / symlink では対応出来ない。 ¡ spring-gradle-plugins: Multimodule gradle project performance improvement. ¡ e.g.) Fix: “High CPU usage when identifying local projects in large multi-project builds” https://github.com/spring-gradle-plugins/dependency-management-plugin/pull/289 ¡ Motivation: Large multimodule Gradle project (~ 数百) needs long time to IntelliJ reload. ¡ Feature branch model to trunk based development transformation. ¡ https://linedevday.linecorp.com/2020/ja/sessions/6992/
  5. Kotlin & Testing in my work (LINE Manga) ¡ -*/&ϚϯΨ

     ೥໨ͷεϚʔτϑΥϯ޲͚ΞϓϦέʔγϣϯʢ 8FCʣ ¡ 1FSM4FSWFS4JEF,PUMJO΁ͷ .JHSBUJPOத ೥໨ ¡ ,PUMJOͷ 4FSWFS4JEFͰͷ࢖ΘΕํ ¡ 4QSJOH#PPU.7$ 3FTU+40/"1* ¡ .POPSFQPTJUPSZ (SBEMFNVMUJNPEVMFQSPKFDU "1* #BUDIFUDʜͷ .PEVMBSNPOPMJUI˞ ¡ 5FTUFECZ+6OJU,PUFTU GVMM$*GPSFWFSZ13 ¡ ˞͍͔ͭ͘ͷίϯϙʔωϯτ͸ଞνʔϜʹΑΓطʹ .JDSP 4FSWJDFT ͱͯ͠ఏڙ͞Ε͍ͯΔ ¡ -*/&"VUI #MMMJOH *NBHF#MPC #JH%BUB "QQ1VTI ¡ ˞ .PEVMBS NPOPMJUI .POPSFQP GVMM$*ͳͷͰ෦඼ͷ࠶ར༻ɺ͕໰୊ແ͘͠΍͍͢ɻ
  6. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡

    'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH
  7. 4PGUXBSF5FTUJOHʹ͓͚Δ l'JYUVSFzͱ͸ ¡ 'JYUVSF KJH KB࣏۩ʢ͙͡ʣ ¡ ݩͷҙຯʣ࡞ۀΛ͢Δࡍʹɺ ର৅ҐஔͷݻఆͳͲͰ࡞ۀΛิॿ͢Δ ¡

    ޻࡞ػցͦͷ΋ͷͰ͸ͳ͍͕ɺ޻࡞͢ΔࣄΛॿ͚ͯ͘ΕΔ ¡ ޻࡞Λ҆શʹɾਖ਼֬ʹɾૣ͘Ͱ͖Δ ¡ 4PGUXBSF 5FTUJOHͷจ຺ʢࠓ೔ͷ࿩ʣͰ͸ ¡ 5FTUͷͨΊͷɾ5FTU ΛηοτΞοϓ͢Δ ςετσʔλ΍ϝιου ¡ .PDL)FMQFS౳ͱݺ͹Ε͍ͯͨΓ΋͢Δʁ ¡ 4FSWJDFDMBTT౳ͷ NPLDJOHͱ΍΍͍͜͠Ͱ͢Ͷɻ -VJHJ;BOBTJ  ౤ߘऀࣗ਎ʹΑΔஶ࡞෺ $$#:4"DB IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJEʹΑΔ
  8. Fixture の説明 in Wikipedia, JUnit4’s Cookbook. ςετΛ࣮ߦɺ੒ޭͤ͞ΔͨΊʹඞཁͳঢ়ଶ΍લఏ৚݅ ͷू߹ΛɺϑΟΫενϟͱݺͿɻ 'SPN8JLJQFEJBʰY6OJUʱ IUUQTKBXJLJQFEJBPSHXJLJ96OJU

    'SPNIUUQTKVOJUPSHKVOJUDPPLCPPLIUNM 5FTUTOFFEUPSVOBHBJOTUUIFCBDLHSPVOEPGBLOPXOTFUPGPCKFDUT5IJTTFU PGPCKFDUTJTDBMMFEBUFTUGJYUVSF8IFOZPVBSFXSJUJOHUFTUTZPVXJMMPGUFOGJOE UIBUZPVTQFOENPSFUJNFXSJUJOHUIFDPEFUPTFUVQUIFGJYUVSFUIBOZPVEPJO BDUVBMMZUFTUJOHWBMVFT 5PTPNFFYUFOU ZPVDBONBLFXSJUJOHUIFGJYUVSFDPEFFBTJFSCZQBZJOHDBSFGVM BUUFOUJPOUPUIFDPOTUSVDUPSTZPVXSJUF)PXFWFS BNVDICJHHFSTBWJOHTDPNFT GSPNTIBSJOHGJYUVSFDPEF0GUFO ZPVXJMMCFBCMFUPVTFUIFTBNFGJYUVSFGPS TFWFSBMEJGGFSFOUUFTUT&BDIDBTFXJMMTFOETMJHIUMZEJGGFSFOUNFTTBHFTPS QBSBNFUFSTUPUIFGJYUVSFBOEXJMMDIFDLGPSEJGGFSFOUSFTVMUT 'SPNIUUQTKVOJUPSHKVOJUDPPLCPPLIUNM ʰςετΛॻ͍͍ͯΔͱɺ࣮ࡍʹ஋Λݕূ͢ΔΑΓ΋ 'JYUVSF ΛηοτΞοϓ͢ΔͨΊ ͷίʔυΛॻ͘΄͏ʹ͕͔͔࣌ؒͬͯ͠·͏͜ͱ͕Α͋͘Γ·͢ɻʱ ʰ$POTUSVDUPS ͷॻ͖ํΛ޻෉͢Ε͹ 'JYUVSF ͷηοτΞοϓ࣌ؒ͸࡟ݮͰ͖Δ͔΋͠ Εͳ͍ɻͰ΋΋ͬͱՁ஋͕͋Δͷ͸ 'JYUVSF ؔ܎ͷίʔυΛڞ༗͢Δ͜ͱͩʱ
  9. ຊ೔ͷൃදͷ͖͔͚ͬ Կނ 'JYUVSF ؅ཧʹ 'PDVT ͢Δͷ͔ʁ ¡ ࣗ෼ͷதͰͷ՝୊ҙࣝ ¡ पΓͷϝιουʹ͋ΘͤͨΒςετίετ͕͕͋ͬͯ͠·͏ɺͱ͍͏ܦݧɻ

    ¡ 3FRVFTU$POUFYU ͷΑ͏ͳܗͰܕʹ͸ΊΔͷ͸ྑ͍͚Ͳɺςετ͕ॻ͖ʹ͍͘ࣄ͕͋Δɻ ¡ ͦͷΠϯελϯεͲ͏࡞Δͷʁ ¡ ෆཁͳϑΟʔϧυʹ͸ԿΛೖΕΔ΂͖ʁ ¡ ྫʣΠϯελϯε͕࡞Γʹ͍͘ͱɺ࠷খݶͷҾ਺ͷ .FUIPE Λఆٛͨ͘͠ͳͬͯ͠·͏ ¡ GVOCVJME)FMMP.FTTBHF DUY3FRVFTU$POUFYU  มߋʹରͯ͠ด͍ͯ͡Δ ¡ 'VOCVJME)FMMP.FTTBHF OBNF4USJOH OPX*OTUBOU  ݴޠͰϝοηʔδΛม͍͑ͨͱࢥͬͨΒʁ ¡ ςετΛॻ͘ͷ͕΋ͬͱ؆୯ʹͳΒͳ͍͔ʁ ¡ ςετ͕ͳΜͱͳ͘ಡΈʹ͍͘ɾͪ͝Ό͍͍ͭͯΔ ¡ ΋ͪΖΜςετର৅͕ͦ΋ͦ΋ෳࡶɾద੾ʹઃܭ͞Ε͍ͯͳ͍Մೳੑ΋͋Δɻ ¡ ςετΛಡΉͷ͕΋ͬͱ؆୯ʹͳΒͳ͍͔ʁ
  10. 適切な Fixture 管理がもたらすメリット ¡ 5FTU3FBEBCJMJUZ ¡ ద੾ʹ؅ཧ͞Εͨ 'JYUVSF͸ʰ5FTUͷՄಡੑʱΛ޲্ͤ͞·͢ ¡ 5FTU8SJUBCJMJUZ

    ¡ ؆୯ʹॻ͚Ε͹ɺ΋ͬͱଟ͘ͷ 5FTUΛɺద੾ͳλΠϛϯάͰɺ଎͘ॻ͚ΔΑ͏ʹͳΓ·͢ɻ ¡ 4DBMF.FSJU$PEFVOJGJDBUJPO ¡ ద੾ʹ 'JYUVSF Λ؅ཧ͢Ε͹ʢཁίετʣɺ ଞͷ։ൃऀʹ΋࢖ΘΕΔࣄͰ։ൃޮ཰্͕͕Γ·͢ʢʴʴʣ ¡ 4IBSFE -JCSBSZ6UJMJUZ ࣮૷ͱڞʹɺ'JYUVSF΋ఏڙ͢ΔࣄͰɺ 5FTUઃܭ͔Βࣗવʹ 1SPEVDUJPO $PEF ͷઃܭͷڞ௨Խ͕ੜ·ΕΔ͜ͱ͕ظ଴Ͱ͖Δ
  11. 5FTU 'JYUVSF ར༻ͷࣦഊྫʢ%BSL 4JEFʣ ¡ ࣗ෼͸ʰ؆୯ʹॻ͚Δʱ͕ ଞͷਓ͕ʰԿΛςετ͍ͯ͠Δͷ͔ʱ͕ղΓʹ͍͘ίʔυ ¡ ςετίʔυ͸ɺ׬શʹ%3:ʢ܁Γฦ͠ΛࣙΊΔʣʹͳΔͷͰ͸ͳ͘ɺ%".1 Λ໨ࢦ͢΂͖Ͱ͋Δࣄ

    ͕ଟ͍ɻͭ·Γɺʮઆ໌త͔ͭҙຯ͕෼͔Γ΍͍͢ݴ͍ճ͠ʢ%FTDSJQUJWF "OE .FBOJOHGVM 1ISBTF ʯΛਪ঑͢Δͱ͍͏͜ͱͩɻগʑͷॏෳ͸ɺͦΕ͕ςετΛ୯७͔ͭ໌֬ͳ΋ͷʹ͢ΔݶΓɺ ໰୊ແ͍ɻ ¡ 'SPNʰ(PPHMF ͷιϑτ΢ΣΞΤϯδχΞϦϯάʱ 4FD QQॳ൛ FOIUUQTBCTFJMJPSFTPVSDFTTXF CPPLIUNMDIIUNMUFTUT@BOE@DPEF@TIBSJOH@EBNQDPNNB@OPU@ES ¡ ςετίʔυͰ͸ɺ%3:ʹ͢Δ͜ͱʹ༂ىʹͳΒͳ͍Ͱ͍ͩ͘͞ɻ ಉ͡ίʔυΛ܁Γฦͯ͠΋͔·͍ ·ͤΜɻ ૉ௚ʹɺ۪௚ʹɺ୯७ʹɻ·ͯ͠Կ͔Λந৅Խ͢ΔϝϦοτ͸΄΅ͳ͍Ͱ͠ΐ͏ɻ ¡ 'SPNIUUQTHJUIVCDPNVCJFPTTLPUMJODPEJOHTUZMF
  12. 好みっぽい話になってしまう(?) ¡ 好みっぽい話になってしまう ¡ そもそも check する必要がない Fixture の生成方法、 というのは大きなテーマ

    Fixture をどう定義するかを考えると どうチェックするのか、 の話は省略できる (同じタイミングでできる)
  13. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡

    'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&pYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTpYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUpYUVSFT QMVHJO ¡ $MPTJOH
  14. Test Fixture あれこれ ¡ 今まで試した・見てきた方法 ¡ (private) fun / val

    fixture ¡ STATIC_FINAL_FIXTURE ¡ fun mockTargetClass() fixture ¡ Fixture as default value? ¡ Fixture in component. ¡ Random<Fixture>
  15. (private) fun / val fixture ¡ ઌ΄Ͳͷྫɾશͯͷجຊ ¡ ςετΫϥεʹ෇ਵ͢Δ GJYUVSFΛɺ

    ಉҰ $MBTT಺ͷෳ਺ςετͰ࢖͍ճ͢ɻ ¡ 1SPT ¡ ڽॖ౓͸ߴ͍ ¡ ͕ɺ݁ہεΫϩʔϧൣғ֎ͩͱ໌ࣔతͱ͸ݴ͍͕͍ͨ ¡ 'JYUVSF มߋͷӨڹൣғΛݶఆͰ͖Δ ¡ $POT ¡ ΫϥεΛލ͍Ͱ࠶ར༻͞Εͳ͍ɻ ¡ ςετʹΑͬͯಉ໊͡લͷ GJYUVSFͷఆ͕ٛ ҟͳΔࣄ΋
  16. STATIC_FINAL fixture ¡ 他のクラスでも再利用できるように val (static final) や fun に切り出して共有

    ¡ Pros ¡ Class を越えた共有ができるようになる。 ¡ Mutable な値を val 定義して問題になる事も。。。 ¡ なのでたまに fun で ¡ Cons ¡ 巨大クラスになりがち(許容できることも) ¡ 見つかりにくいので再利用されにくい ¡ 特にクラス分割してしまったりすると
  17. Fixture in default value? ¡ MoSvaSon: ¡ もう Produc:on code

    に default value すれば楽なのでは無いか? ¡ Produc'on code も変更したいところだけ変更すれば変更行数が少ない? ¡ フィールドを追加してもテストを更新しなくてよい? ¡ Pros ¡ 別のコンパイル単位での利用も簡単 ¡ Cons ¡ 影響範囲を限定できるのではなく、実際は隠してしまう。 ¡ などなど
  18. Fixture in companion ¡ Companion object の中に(≒ static object として;Java)定義

    ¡ Pros ¡ 比較的見つけやすい(?) ¡ コンパイル単位を越えて簡単に使える ¡ Cons ¡ Production code への混入(が default value 程ではない) ¡ などなど
  19. Random<FixtureType> ¡ 乱数でインスタンスを初期化してテスト ¡ Motivation ¡ いちいち new するのはめんどうだ(引数が) ¡

    かといって default 値を入れるのは production code を汚す ¡ Fixture 管理もしたくない ¡ Pros ¡ 手間が無く簡単 ¡ 共有しないので、共有ルールを覚える必要は無い ¡ Cons ¡ テストに新たな不確定要素が増える ¡ 意味のある値はいれられない・にくい(例:User Agent ¡ Not DAMP. 純粋に Random を利用すると、 『つまりどうなる?』 が解りにくい(DAMP)
  20. Fixture by mock ¡ 4FSWJDF౳ͷ .PDLJOHʹ͔ͭ͏ MJCSBSZΛ pYUVSFʹ΋ར༻͢Δ ¡ 1SPT

    ¡ 4FSWJDF ౳ͷ NPDLJOHͱಉ͡΍Γ͔ͨɻ ¡ *OUFSBDUJPOΛશͯ໌Β͔ʹͰ͖Δ ¡ ྫʣಛఆͷ 'JFME͔͠৮͍ͬͯͳ͍ࣄΛ͔֬ʹ͍ͨ͠ ¡ $POT ¡ ʰσʔλɾঢ়ଶʱͰ͸ͳ͘ʰ࣮૷ʱ ͷςετʹͳͬͯ͠·͏
  21. 一覧 ࠶ར༻Մೳੑ ຊ൪ίʔυԚછ ݟ͔ͭΓ΍͍͔͢ %".1 QSJWBUFWBM ❌ in class only

    🟢 ❌ 🟢 45"5*$@'*/"- 🟢 🟢 ⚠ ⚠ EFGBVMUWBMVF 🟢 ❌ 🟢 ⚠ DPNQBOJPOPCKFDU 🟢 ❌ 🟢 ⚠ SBOEPN 'JYUVSF ❌ 🟢 ❌ ❌ NPDL'JYUVSF ❌ 🟢 ❌ 🟢 (実装をテスト) ˞ ຊ౰͸ɺʰͲͷΑ͏ʹΠϯελϯεΛ࡞Δ͔ʱʰͲͷΑ͏ʹڞ༗͢Δ͔ʱͷೋ͕࣠͋Δ
  22. Fixture 管理あれこれ / まとめ ¡ มߋʹڧ͍ɺͱݺ͹ΕΔύλʔϯ͸࣮ࡍ͸ʰมߋΛӅ͢ʱํ๏Ͱ͋Δࣄ΋͋ΔɻʢEFGBVMUGJYUVSF ¡ Ӆ͞ͳ͚Ε͹ίϯύΠϧ࣌ʹؾ͚ͮΔɻ ¡ Ӆͨ͠Βɿ࣮ߦ࣌͠ͳ͍ͱؾ͚ͮͳ͍ɻ

    ¡ ݱ࣮ͷݱ৔ ¡ ʰઌ݄ 6TFSΫϥεʹϑΟʔϧυ͕૿͚͑ͨͲɺͦͷͱ͖͸Ұ෦ͷ .FUIPE ͔͠ରԠͯ͠ͳ͍Έ͍ͨɻ ඇରԠͷ .FUIPE ͔Βऔಘͨ͠৔߹͸ຊདྷͷঢ়ଶͱ͸ؔ܎ແ͘ɺϑΟʔϧυ͕ৗʹ GBMTFʹͳͬͪΌ͏ΜͩΑͶɻɻɻɻʱ ¡ 1SPEVDUJPODPEFʢTSDNBJOʣʹॻ͚͹ɺ࠶ར༻ՄೳʹͳΔɻɻɻʁ ¡ ΋΍ͬͱ͢Δɻʢʣ ¡ ֎෦ -JCSBSZ ͷ 'JYUVSF ͸Կॲʹॻ͘ʁ ໰୊͕ൃੜɻ ¡ Ϋϥεͷۙ͘ʢ 1SPEVDUJPODPEFʣʹॻ͚͹ݟ͚ͭ΍͍͢ɺԕ͘ʹॻ͍ͯݟ͚ͭ΍͘͢͢ΔͨΊʹ͸ɻɻɻɻʁ ˠඞཁͳͷ͸ɺ1SPEVDUJPODPEFʹӨڹΛ͓΅Αͣ͞ɺ֎෦ϥΠϒϥϦΫϥεʢ+BWBؚΉʣʹ΋࢖͑ͯɺ ॻ͖ํΛεέʔϧͨ͠ͱ͖ʹʢ෼ࢄͯ͠ॻ͍ͨͱ͖ʹʣݟ͚ͭ΍͍͢ 'JYUVSF ͷॻ͖ํɻ
  23. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡

    'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&pYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTpYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUpYUVSFT QMVHJO ¡ $MPTJOH
  24. ::class.fixture() pattern ¡ 'JYUVSFΛର৅Ϋϥεʢ,$MBTTʣͷ֦ுؔ਺ͱͯ͠ఆٛ ¡ ֦ுؔ਺ͳͷͰɺ1SPEVDUJPO DPEFΛԚછ͠ͳ͍ɻ ¡ 1SPT ¡

    ֦ுؔ਺ͱͯ͠࠶ར༻Λલఏ ¡ -JCSBSZ ͷίʔυʹ΋ར༻Մೳ ¡ +BWBͰॻ͔Ε͍ͯͯ΋ 0, ¡ $POT ¡ ֦ுؔ਺Ͱ͢ʂ ར༻͸ܭըతʹ ¡ 1SPEVDUJPODPEFͱ෼཭͞ΕΔͷͰɺ $PNQJMFڥքΛӽ͑Δҝʹ 1MVHJO ͕ඞཁ
  25. Why KClass? companion object に対して拡張関数を定義できるが、、 ¡ DPNQBOJPOPCKFDU ʹର֦ͯ͠ுؔ਺Λఆٛ͢Ε ͹΋ͬͱγϯϓϧʹ $MBTTGJYUVSF

    Ͱݺͼग़ͤΔ ¡ ͕ɺۭͷ DPNQBOJPOPCKFDU͕ඞཁ ¡ एׯ QSPEVDUJPODPEFʹӨڹ ¡ ֎෦ͷɾ+BWB ͷΫϥεʹద༻Ͱ͖ͳ͍ ¡ ,$MBTT JOTUBODF͸ +BWB ͷΫϥεʹରͯ͠΋औಘ Մೳ
  26. &YBNQMF +BWB Ͱॻ͔ΕͨΫϥε΋ର৅ʹ ¡ +BWBͰॻ͔ΕͨΫϥε΋ ,$MBTT͸͋Δ ¡ ,$MBTT Λܦ༝ͯ͠ܕʹٖࣅతͳ֦ுؔ਺Λ࡞੒ ¡

    1SPEVDUJPO DPEFଆͰ EFGBVMU஋͕ແ͍ɾ DPQZNFUIPE͕ແ͍৔߹Ͱ΋ GJYUVSF͕໌ࣔ తʹ࡞ΕΔɻ
  27. Example) Mock / Helper へのヒントとして ¡ mockk<HttpServletRequest> ¡ 自分で mock

    してしまいがちだが、、、 ¡ spring-boot-starter-test に MockHttpServletRequest がある ¡ 知らないとなかなか見つからない ¡ fixture にヒントを書く
  28. DMBTTGJYUVSF QBUUFSO·ͱΊ ¡ ,$MBTTΠϯελϯεʹର͢Δ֦ுؔ਺ͱͯ͠ 'JYUVSF Λఆٛ ¡ ,$MBTT5Πϯελϯεʹର͢Δ֦ுؔ਺Λॻ͍ͯ 5ܕ΁ͷ֦ுؔ਺ͱݟͳ͢ ¡

    ୳͠΍͍͢ʢ*%& 'SJFOEMZʣ ¡ ֎෦ίʔυɾ+BWB ʹ΋ద༻Մೳ ¡ ͦΕͧΕ͕ಠཱͨ͠৔ॴʹॻ͚Δ ¡ ֦ுؔ਺ͷ͝ར༻͸ܭըతʹ ¡ #VU౓ʰDMBTTpYUVSF Ͱ୳ͤΔʱ͕νʔϜʹड͚ೖΕΒΕΕ͹ָɻ
  29. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡

    'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`T+BWB5FTU'JYUVSF1MVHJO ¡ $MPTJOH
  30. +BWB5FTU'JYUVSFT1MVHJO ͷ঺հ ¡ +BWB5FTU'JYUVSFT1MVHJO ¡ (SBEMF ެࣜͷ 'JYUVSF ڞ༗༻ 1MVHJO

    ¡ (SBEMF6TFS(VJEF +BWB5FTUJOH 6TJOHUFTUpYUVSFT ¡ IUUQTEPDTHSBEMFPSHDVSSFOUVTFSHVJEFKBWB@UFTUJOHIUNMTFDKBWB@UFTU@pYUVSFT ¡ Ͱ͖Δ͜ͱʣNPEVMFڥքΛӽ͑ͯ 'JYUVSFΛ࠶ར༻Ͱ͖ΔΑ͏ʹͳΔ SFQPTJUPSZTFSWFS ¡ TSDNBJOʹॻ͍ͨΒ QSPEVDUJPODPEFࠞೖ ❌ ¡ TSDUFTUʹॻ͍ͯ΋ڞ༗Ͱ͖ͳ͍ ❌
  31. +BWB5FTU'JYUVSFT1MVHJO ͷ࢖͍ํʢηοτΞοϓʣ ¡ NBJO UFTUͷଞʹ lUFTU'JYUVSFTzTPVSDFTFU͕Ͱ ͖Δ ¡ Ϟδϡʔϧ୯ମʹ͓͍ͯ ¡

    UFTU'JYUVSFT͸ NBJOͷ $MBTT͕ݟ͑Δ ¡ UFTU͸ UFTU'JYUVSFTͷ $MBTT͕ݟ͑Δ NBJO UFTU'JYUVSFT UFTU
  32. QSPKFDU TUPSBHFVTFS +BWB5FTU'JYUVSFT1MVHJO ͷԿ͕خ͍͠ͷ͔ ¡ Ϟδϡʔϧ୯ମͰ͸Կ΋خ͘͠ͳ͍ ¡ 'JYUVSF ͸ଞͷϞδϡʔϧͰ΋࠶ར༻Ͱ͖Δɺͱ͍͏ͱ͜Ζʹخ͕͋͠͞Δ ¡

    ྫɿTFSWFSNPEVMFͰɺTUPSBHFNPEVMFͷ 'JYUVSF Λ࢖͍ճ͍ͨ͠ QSPKFDU BQJTFSWFS EFQFOEFODZ\ JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz ^ QSPKFDU CBUDITVTFS EFQFOEFODZ\ JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz ^
  33. QSPKFDU TUPSBHFVTFS +BWB5FTU'JYUVSFT1MVHJO ͷ࢖͍ํʢར༻ʣ NBJO UFTU'JYUVSFT UFTU QSPKFDU BQJTFSWFS EFQFOEFODZ\

    GPSNBJO JNQMFNFOUBUJPO QSPKFDU lTUPSBHFVTFSz GPS5FTUJOH UFTU*NQMFNFOUBUJPO UFTU'JYUVSFT QSPKFDU lTUPSBHFVTFSz ^ QSPKFDU CBUDITVTFS
  34. +BWB5FTU'JYUVSFT1MVHJO ·ͱΊ Gradle 公式の Fixture 管理用 Plugin Fixture を個別 source

    set として管理 Module を越えた、 Fixture 再利用を可能にする Fixture のコピー&ペーストしなくてよくなる
  35. 本セッションの流れ ¡ ࣗݾ঺հɾഎܠͷ૝ఆ ¡ 5FTUͱ l'JYUVSFz ͷؔ܎ ¡ 'JYUVSF؅ཧͷॏཁੑ ¡

    'JYUVSF؅ཧ͋Ε͜Ε ¡ $"1*5"-@$"4&GJYUVSF ¡ 'JYUVSFJOEFGBVMUWBMVF ¡ 'JYUVSFJODPNQPOFOU ¡ 3BOEPN'JYUVSFFUDʜ ¡ DMBTTGJYUVSF QBUUFSOͷ঺հ ¡ (SBEMF`TKBWBUFTUGJYUVSFT QMVHJO ¡ $MPTJOH
  36. まとめ ¡ 5FTU'JYUVSF؅ཧ͸ॏཁʢˍ໘ന͍ʣ ¡ ໌֬ͰಡΈ΍͍͢ςετͷͨΊɻ݁Ռͱͯ͠ςετͷॻ͖΍͢͞ͷͨΊɻ ¡ ʰͳΜͱͳ͘ΊΜͲ͍͘͞ςετʱΛ୤٫͢Δͷʹඞཁͳͭ ¡ 'JYUVSFΛ੔ཧͨ͠Βɺઃܭ΍ࣄલ४උͷվળ఺͕໨ཱͭΑ͏ʹͳΔ͔΋ ¡

    ͨͩ͠ɺ'JYUVSF ؅ཧͱڞʹ໌ࣔతͳ DIFDLɺ΋େࣄɻʢ%".1આ໌త͔ͭҙຯ͕෼͔Γ΍͍͢ݴ͍ճ͠ʣ ¡ DMBTTGJYUVSF QBUUFSO,$MBTT ֦ுؔ਺ͱͯ͠ॻ͘͜ͱͰɺ*%& ͷԸܙ΋ड͚ΒΕͯڞ༗ʹศར ¡ ͦ͜ʹͳ͍ ଟ෼ଞʹ΋ॻ͔Ε͍ͯͳ͍ νʔϜͱͯ͠௥Ճ͢Δɺͷ൑அ ¡ 5FTU'JYUVSFҎ֎ʹ΋࢖͑Δʢ+BWB`T#VJMEFSSFQMBDFNFOU౳ʣ ¡ (SBEMFެࣜ +BWB5FTU'JYUVSFT1MVHJOศར ¡ lKBWBzͱ͍͍ͭͯ·͕͢ɺ౰વ ,PUMJOͰ΋ศརʹ࢖͑Δ