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
220
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
240
JUnitで闘うレガシーコード改善
yutasaito
3
910
Other Decks in Technology
See All in Technology
アジャイルな開発チームでテスト戦略の話は誰がする? / Who Talks About Test Strategy?
ak1210
1
830
AWSアカウントのセキュリティ自動化、どこまで進める? 最適な設計と実践ポイント
yuobayashi
7
1.6k
JAWS DAYS 2025 アーキテクチャ道場 事前説明会 / JAWS DAYS 2025 briefing document
naospon
0
2.8k
x86-64 Assembly Essentials
latte72
3
420
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
19k
What's new in Go 1.24?
ciarana
1
120
JavaにおけるNull非許容性
skrb
2
2.7k
Platform Engineeringで クラウドの「楽しくない」を解消しよう
jacopen
4
210
RayでPHPのデバッグをちょっと快適にする
muno92
PRO
0
200
Snowflake ML モデルを dbt データパイプラインに組み込む
estie
0
110
Amazon Athenaから利用時のGlueのIcebergテーブルのメンテナンスについて
nayuts
0
110
AIエージェント入門
minorun365
PRO
33
20k
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
13
1k
Rails Girls Zürich Keynote
gr2m
94
13k
KATA
mclloyd
29
14k
A better future with KSS
kneath
238
17k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
27
1.9k
Scaling GitHub
holman
459
140k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
For a Future-Friendly Web
brad_frost
176
9.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
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"); } }
ଞʹ৭ʑ͋Γ·͢ʂ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠