Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
サービス間をテストするフレームワーク集
Shin'ya Ueoka
December 15, 2021
Technology
0
83
サービス間をテストするフレームワーク集
2021-12-15 開催 JJUGナイトセミナー「おうちで!ビール片手にLT大会!」でお話した資料です
https://jjug.doorkeeper.jp/events/129543
Shin'ya Ueoka
December 15, 2021
Tweet
Share
More Decks by Shin'ya Ueoka
See All by Shin'ya Ueoka
技術書典12協賛企業サイボウズゲストトーク
ueokande
0
55
kintone.comを支える技術
ueokande
0
130
SLO策定とアラート設定までの長い道のり
ueokande
6
2k
オンラインイベントを 半年運営して気づいたこと
ueokande
0
55
インフラ開発チームがプロダクトチームに体験入部したはなし
ueokande
1
400
kintone.comのAWS移行と その舞台裏
ueokande
4
1.7k
OSSでキレイな本を 作りたい話
ueokande
0
210
サイボウズとOSSの付き合い方
ueokande
0
680
究極のInfrastructure as Codeを目指して
ueokande
6
4k
Other Decks in Technology
See All in Technology
psql, my favorite tool!
nuko_yokohama
1
180
合同IT企業説明会から学ぶエンジニア向けの広報戦略
nagutabby
1
250
GitOps共有会
johnmanjiro13
0
160
ニコニコ生放送におけるWebフロントエンドBFFサーバーのKubernetes移行事例の紹介
himenon
4
970
Continuous Architecture Design for Modernization
humank
3
560
年700万円損するサーバレスの 認可システムをご紹介します!!
higuuu
3
350
金融スタートアップの上場準備で大事にしたマインドセット / 2022-08-04-the-mindset-in-preparing-for-ipo
stajima
0
330
第22回 MLOps 勉強会:みてねのMLOps事情
tonouchi510
1
1.1k
聊聊 Cgo 的二三事
david74chou
0
350
SBOMを利用したソフトウェアサプライチェーンの保護
masahiro331
1
200
Identidad en Web3
dschenkelman
0
100
Power Automate for desktopで 配信環境を改善してみた話
akiika
0
340
Featured
See All Featured
Fontdeck: Realign not Redesign
paulrobertlloyd
73
4.1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
638
53k
Build your cross-platform service in a week with App Engine
jlugia
219
17k
Embracing the Ebb and Flow
colly
73
3.4k
What the flash - Photography Introduction
edds
63
10k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
151
13k
Intergalactic Javascript Robots from Outer Space
tanoku
260
25k
Clear Off the Table
cherdarchuk
79
290k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
226
15k
Building Adaptive Systems
keathley
25
1.2k
Faster Mobile Websites
deanohume
294
29k
Ruby is Unlike a Banana
tanoku
91
9.3k
Transcript
αʔϏεؒΛςετ͢Δ ϑϨʔϜϫʔΫू αΠϘζגࣜձࣾ ্Ԭ ਅ (@ueokande) 2021-12-15. JJUGφΠτηϛφʔʮ͓͏ͪͰʂϏʔϧยखʹLTେձʂʯ
Me • αΠϘζגࣜձࣾ • άϩʔόϧ͚B2BαʔϏεͷ όοΫΤϯυΛ࡞͍ͬͯ·͢ • ݱͰKotlin +
Spring Boot͕ϝΠϯ 2
ຊͷ͓ • ෳαʔϏε͕ϓϩμΫτΛߏ͢Δ࣌ʢMicroservice, SOA, …ʣ • αʔϏεؒͷΓऔΓΛͲ͏ͬͯςετ͢Δ͔ʁ • REST API௨৴ͷݕূʹཱͭϑϨʔϜϫʔΫΛհ
3 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
հϑϨʔϜϫʔΫ • Mockito … ΫϥΠΞϯτͷ࣮ͱϏδωεϩδοΫΛ • WireMock … ϞοΫαʔόʔΛཱͯͯΫϥΠΞϯτ࣮Λςετ •
Pact … αʔϏεؒ௨৴ͷAPIͷมߋΛݕ 4
Mockito • JavaͷΠϯλʔϑΣΠεɺΫϥεΛϞοΫ • ΫϥΠΞϯτ࣮ΛϞοΫͯ͠ϏδωεϩδοΫ୯ମΛςετ 5 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
͜͜ΒΜͷςετ
Mockito͔͍͔ͭͨ • MockitoΛͬͯΫϥΠΞϯτ࣮ͷϞοΫΛهड़ • ϩδοΫ୯ମΛςε͠ɺΫϥΠΞϯτར༻͞Ε͔ͨݕূ 6 val client = mock<BClient>()
whenever(client.getItems()) .thenReturn(Arrays.asList(item1, …)) val logic = ItemLogic(bClient) val actual = sut.calc() assertEquals("...", actual) verify(bClient, times(1)).getItems() ϞοΫΫϥΠΞϯτͷ࡞ ϞοΫΫϥΠΞϯτΛͯ͠ ରΫϥεʢϏδωεϩδοΫʣͷݕূ MockΫϥΠΞϯτ͕ར༻͞Ε͔ͨݕূ ※ Kotlinͷίʔυྫ
WireMock • ϞοΫͷϨεϙϯεΛฦ͢HTTPαʔόʔΛཱͯΔ • HTTPαʔόʔϦΫΤετΛهͯ͠ظ͢ΔϦΫΤετ͔ݕূ 7 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
͜͜ΒΜͷςετ
WireMock͔͍͔ͭͨ • ϦΫΤετʹର͢ΔϨεϙϯεΛఆٛͯ͠ϞοΫαʔόʔΛىಈ • ΫϥΠΞϯτ࣮ͱɺൃߦ͞ΕͨϦΫΤετ͕ਖ਼͍͔͠ݕূ 8 val server = WireMockServer(12345)
server.stubFor( WireMock.post(“/v1/item/1“) .willReturn(aResponse().withBody("{ ... }”))) server.start() val client = BClientImpl("127.0.0.1", 12345) List<Items> item = bClient.getItem(1L) assertEquals(10, actual.size) server.verify( postRequestedFor(urlPathEqualTo("/v1/items")) .withRequestBody(equalToJson("{ ... }")) ) ϞοΫαʔόʔͷ࡞ͱىಈ ϦΫΤετͷൃߦͱΓͷݕূ ࣮ߦ͞ΕͨϦΫΤετͷݕূ
Pact/Pact JVM • αʔϏεؒͷAPIͷৼΔ͍Λ୲อ͢ΔϑϨʔϜϫʔΫ 1. ίϯγϡʔϚʔɺར༻APIͷظ͢ΔϦΫΤετɾϨεϙϯεʢܖʣΛఆٛ 2. ίϯγϡʔϚʔɺΫϥΠΞϯτ࣮͕ܖͷ௨ΓʹৼΔ͏͔ݕূ 3. ϓϩόΠμʔɺܖͷϦΫΤετʹର͠ظͷϨεϙϯεΛฦ͔͢ݕূ
9 αʔϏε" $POTVNFS αʔϏε# 1SPWJFS ܖ ϞοΫ ϞοΫ ϦΫΤετ Ϩεϙϯε ϦΫΤετ Ϩεϙϯε ࡞ ݕূ ᶃ ᶄ ᶅ json
Pact JVM͍ํʛܖͷఆٛ • ίϯγϡʔϚʔଆ͕ར༻͢ΔAPIͷಈ࡞ΛDLSͰఆٛ 10 @Pact(provider = “service-b", consumer =
“service-a") fun getItemPact(builder: PactDslWithProvider): V4Pact { builder .given("item1 and item2 exist") .uponReceiving("get all items") .method(“GET”).matchPath(“/v1/item/1“) .willRespondWith().status(200).body( LambdaDsl.newJsonBody { it -> it.`object` { it.stringType(“name", “pen") it.numberType(“cost", 100) } } ) } ϦΫΤετʹର͢Δظ͢ΔϨεϙϯεΛఆٛ
Pact JVM͍ํʛίϯγϡʔϚʔͷݕূ • هड़ͨ͠ܖʹରͯ͠ΫϥΠΞϯτ࣮͕ਖ਼͘͠ৼΔ͏͔ݕূ • ϞοΫαʔόʔ͕ىಈͯ͠HTTPϦΫΤετΛهɾݕূ 11 @Test @PactTestFor(providerName =
“service-b", pactMethod = "getItemPact") fun getItem(mockServer: MockServer) { val client = BClientImpl(mockServer.getUrl()) val item = client.getItems(1L) assertEquals("pen", item.name) assertEquals(100, item.cost) }
Pact JVM͍ํʛϓϩόΠμʔͷݕূ • ϓϩόΠμʔ͕ܖ௨ΓͷϨεϙϯεΛฦ͔͢ݕূ • ܖΛͱʹPactϑϨʔϜϫʔΫ͕ࣗಈͰςετ 12 @ExtendWith(SpringExtension::class) @Provider(“service-b") @SpringBootTest(webEnvironment
= SpringBootTest.WebEnvironment.RANDOM_PORT) class ContractTest { @TestTemplate @ExtendWith(PactVerificationInvocationContextProvider::class) fun testTemplate( pact: Pact, interaction: Interaction, context: PactVerificationContext ) { context.verifyInteraction() } }
·ͱΊ • ਖ਼͍͠ϨΠϠʔͰϞοΫͯ͠ਖ਼͘͠ςετ • Mockito … αʔϏεͷΠϯλʔϑΣΠεͱ࣮ΫϥεΛ • WireMock …
ϦΫΤετɾϨεϙϯεΛϞοΫ • Pact … ৗʹมԽ͠ଓ͚ΔαʔϏεؒͷAPIͰഁյతมߋ͕ͳ͍͔νΣοΫ • ͍͠ϨΠϠʔςετɾࣗಈԽͯ҆͠৺ײΛಘΑ͏ 13