Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WireMockでHTTPをモックしよう
Search
YutaSaito
August 05, 2022
Technology
0
280
WireMockでHTTPをモックしよう
2022/8/6 Java Do データアクセスについて聞きたい・話したい!
#javado
YutaSaito
August 05, 2022
Tweet
Share
More Decks by YutaSaito
See All by YutaSaito
依存関係のテストだけじゃないArchUnitのこんな使い方
yutasaito
2
280
JUnitで闘うレガシーコード改善
yutasaito
3
960
Other Decks in Technology
See All in Technology
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
12k
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
5
60k
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
5
1.5k
Oracle Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
2
750
Keynoteから見るAWSの頭の中
nrinetcom
PRO
1
170
BidiAgent と Nova 2 Sonic から考える音声 AI について
yama3133
2
150
旬のブリと旬の技術で楽しむ AI エージェント設計開発レシピ
chack411
1
140
CQRS/ESになぜアクターモデルが必要なのか
j5ik2o
0
720
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
3.6k
国井さんにPurview の話を聞く会
sophiakunii
1
350
製造業から学んだ「本質を守り現場に合わせるアジャイル実践」
kamitokusari
0
450
ソフトウェアエンジニアとAIエンジニアの役割分担についてのある事例
kworkdev
PRO
1
380
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
0
320
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
54
49k
The agentic SEO stack - context over prompts
schlessera
0
580
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
120
Ethics towards AI in product and experience design
skipperchong
1
160
Into the Great Unknown - MozCon
thekraken
40
2.2k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2k
Odyssey Design
rkendrick25
PRO
0
450
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
97
Building an army of robots
kneath
306
46k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.2k
Transcript
!:VUB4BJUP 8JSF.PDLͰ )551ΛϞοΫ͠Α͏
ࣗݾհ wಘҙྖҬ+BWB "84 w͖ͳϓϩٿνʔϜϋϜ wग़౦ wւಓྺະ্ɻ͓͢͢Ίͷ؍ޫඒຯ͍͠͝൧Λڭ͑ͯԼ͍͞ʂ w5XJUUFS!:VUB4BJUP
8JSF.PDLͬͯʁ
)551௨৴͕ൃੜ͢ΔίʔυͰͷࠔΓ͝ͱ w ৽͘͠"1*Λݺͼग़͢ඞཁ͕ੜ͕ͨ͡ɺଓઌͷγεςϜ͕·ͩ࡞ΒΕ͍ͯͳ ͍ͨΊίʔυ͕ಈ͔͘Θ͔Βͳ͍ w ςετڥͰଓઌ"1*͕ظͨ͠Λฦͯ͘͠Εͳ͍ͨΊςετग़དྷͳ͍έ ʔε͕ଘࡏ͢Δ w "1*ͷ௨৴͕ඞཁͳϩδοΫͷςετίʔυΛॻ͚ͳ͍
8JSF.PDLͬͯʁ $MJFOU 4FSWJDF (&5IUUQFYBNQMFDPNIFMMP 0, \lNFTTBHFzlIFMMPz^
8JSF.PDLͬͯʁ $MJFOU (&5IUUQFYBNQMFDPNIFMMP 0, \lNFTTBHFzlIFMMPz^
8JSF.PDLͷಈ͔͠ํ
8JSF.PDLΛಈ͔͢ํ๏େ͖͘छྨ͋Γ·͢ w +BWBͷϥΠϒϥϦΛར༻ͯ͠+6OJUͰىಈ͢Δ w +BSΛμϯϩʔυͯ͠ىಈ͢Δ w %PDLFSΠϝʔδΛىಈ͢Δ
8JSF.PDLΛಈ͔͢ํ๏େ͖͘छྨ͋Γ·͢ w +BWBͷϥΠϒϥϦΛར༻ͯ͠+6OJUͰىಈ͢Δ w +BSΛμϯϩʔυͯ͠ىಈ͢Δ w %PDLFSΠϝʔδΛىಈ͢Δ
+BWBͷϥΠϒϥϦΛར༻ͯ͠+6OJUͰىಈ͢Δ @WireMockTest public class HelloWireMockTest { @Test void helloΛฦ͢(WireMockRuntimeInfo wmRuntimeInfo)
{ stubFor(get("/hello").willReturn(okJson("{ \"message\": \"hello\" }"))); String baseUrl = wmRuntimeInfo.getHttpBaseUrl(); WebTestClient webTestClient = WebTestClient.bindToServer().baseUrl(baseUrl).build(); webTestClient .get() .uri("hello") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus() .isOk() .expectBody() .jsonPath("$.message") .isEqualTo("hello"); } }
8JSF.PDLΛಈ͔͢ํ๏େ͖͘छྨ͋Γ·͢ w +BWBͷϥΠϒϥϦΛར༻ͯ͠+6OJUͰىಈ͢Δ w +BSΛμϯϩʔυͯ͠ىಈ͢Δ w %PDLFSΠϝʔδΛىಈ͢Δ
%PDLFSΠϝʔδΛىಈ͢Δ $ docker run -it --rm -p 8080:8080 wiremock/wiremock:2.33.2 SLF4J:
Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. /$$ /$$ /$$ /$$ /$$ /$$ | $$ /$ | $$|__/ | $$$ /$$$ | $$ | $$ /$$$| $$ /$$ /$$$$$$ /$$$$$$ | $$$$ /$$$$ /$$$$$$ /$$$$$$$| $$ /$$ | $$/$$ $$ $$| $$ /$$__ $$ /$$__ $$| $$ $$/$$ $$ /$$__ $$ /$$_____/| $$ /$$/ | $$$$_ $$$$| $$| $$ \__/| $$$$$$$$| $$ $$$| $$| $$ \ $$| $$ | $$$$$$/ | $$$/ \ $$$| $$| $$ | $$_____/| $$\ $ | $$| $$ | $$| $$ | $$_ $$ | $$/ \ $$| $$| $$ | $$$$$$$| $$ \/ | $$| $$$$$$/| $$$$$$$| $$ \ $$ |__/ \__/|__/|__/ \_______/|__/ |__/ \______/ \_______/|__/ \__/ port: 8080 enable-browser-proxying: false disable-banner: false no-request-journal: false verbose: false $ curl -X POST \ —data '{ "request": { "url": "/hello", "method": "GET" }, "response": { "status": 200, "body": "{ \"message\": \"hello\"} ", "headers": { "Content-Type": "application/json" }}}' \ http://localhost:8080/__admin/mappings/new $ curl http://localhost:8080/hello { "message": "hello"} %
8JSF.PDLͷ͍ํ
ελϒͷ࡞ @WireMockTest public class BasicStubbing { @Test void stubing(WireMockRuntimeInfo wmRuntimeInfo)
{ stubFor(get("/hello").willReturn(aResponse().withStatus(200).withBody("Hello World!"))); WebTestClient webTestClient = WebTestClient.bindToServer().baseUrl(wmRuntimeInfo.getHttpBaseUrl()).build(); webTestClient .get() .uri("/hello") .exchange() .expectStatus() .isOk() .expectBody(String.class) .isEqualTo("Hello World!"); } }
ϦΫΤετϚονϯά 63-ϚονϯάͰਖ਼نදݱΛར༻͢Δ @WireMockTest public class Matching { @Test void urlRegex(WireMockRuntimeInfo
wmRuntimeInfo) { stubFor(get("/users/*").atPriority(10).willReturn(notFound())); stubFor(get(urlMatching("/users/(123|456)")).willReturn(okJson("{ \"message\": \"hello\" }"))); WebTestClient webTestClient = WebTestClient.bindToServer().baseUrl(wmRuntimeInfo.getHttpBaseUrl()).build(); webTestClient .get() .uri(uriBuilder -> uriBuilder.path("/users/{id}").build("123")) .exchange() .expectStatus() .isOk() .expectBody() .jsonPath("$.message") .isEqualTo("hello"); webTestClient .get() .uri(uriBuilder -> uriBuilder.path("/users/{id}").build("789")) .exchange() .expectStatus() .isNotFound(); } }
ϦΫΤετϚονϯά ϦΫΤετͷଐੑΛར༻ͨ͠Ϛονϯά @WireMockTest public class Matching { @Test void header(WireMockRuntimeInfo
wmRuntimeInfo) { stubFor( get("/users/123") .withHeader("Accept", equalTo("application/json")) .willReturn(okJson("{ \"message\": \"hello\" }"))); stubFor(get("/users/123").withHeader("Accept", equalTo("text/plain")).willReturn(ok("hello"))); WebTestClient webTestClient = WebTestClient.bindToServer().baseUrl(wmRuntimeInfo.getHttpBaseUrl()).build(); webTestClient .get() .uri("/users/123") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus() .isOk() .expectBody() .jsonPath("$.message") .isEqualTo("hello"); webTestClient .get() .uri("/users/123") .accept(MediaType.TEXT_PLAIN) .exchange() .expectStatus() .isOk() .expectBody(String.class) .isEqualTo("hello"); } }
ϨεϙϯεςϯϓϨʔτ public class Templating { @RegisterExtension static WireMockExtension wireMockExtension =
new WireMockExtension.Builder() .options( WireMockConfiguration.wireMockConfig() .dynamicPort() .extensions(new ResponseTemplateTransformer(true))) .build(); @Test void templated() { wireMockExtension.stubFor( get("/templated") .willReturn( aResponse() .withBody("{{request.headers.X-Request-Id}}") .withTransformers("respones-template"))); WebTestClient webTestClient = WebTestClient.bindToServer() .baseUrl(wireMockExtension.getRuntimeInfo().getHttpBaseUrl()) .build(); webTestClient .get() .uri("/templated") .header("X-Request-Id", "123") .exchange() .expectStatus() .isOk() .expectBody(String.class) .equals("123"); } }
োΛγϛϡϨʔγϣϯ @WireMockTest public class SimulationgFaults { @Test void timeout(WireMockRuntimeInfo wmRuntimeInfo)
{ stubFor(get("/delayed").willReturn(aResponse().withStatus(200).withFixedDelay(3000))); WebTestClient webTestClient = WebTestClient.bindToServer() .baseUrl(wmRuntimeInfo.getHttpBaseUrl()) .responseTimeout(Duration.ofMillis(2000)) .build(); assertThatThrownBy( () -> { webTestClient.get().uri("/delayed").exchange().expectStatus().isOk(); }) .isInstanceOf(IllegalStateException.class) .hasMessageContaining("Timeout"); } }
ଞʹ৭ʑ͋Γ·͢ʂ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠