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
Migrating to JUnit 5
Search
LINE Developers Taiwan
PRO
October 21, 2020
Technology
3.6k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Migrating to JUnit 5
by Joanna Hu at TWJUG 20201021
https://twjug.kktix.cc/events/twjug202010
LINE Developers Taiwan
PRO
October 21, 2020
More Decks by LINE Developers Taiwan
See All by LINE Developers Taiwan
Building applications in the Gemini API family.
line_developers_tw
PRO
0
2.2k
20260514 - build with ai 2026 - build LINE Bot with Gemini CLI
line_developers_tw
PRO
0
500
2026.04.09_台灣客服協會_從資料重新理解客服_ Charlie Wang
line_developers_tw
PRO
0
54
Zona 台北大學 GDG 分享
line_developers_tw
PRO
0
81k
台大資料分析與決策社 機器學習的商業應用_Rei
line_developers_tw
PRO
0
38
政大數據分析社 機器學習的商業應用_Rei
line_developers_tw
PRO
0
67
Gemini 2025 新功能回顧 LINE Bot 完美結合
line_developers_tw
PRO
0
660
NTUAI企業參訪
line_developers_tw
PRO
0
26k
Data TECH FRESH企業參訪- Amber
line_developers_tw
PRO
0
57k
Other Decks in Technology
See All in Technology
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
1
230
データ基盤をDataformで整えた話 〜 開発環境を添えて 〜
takapy
0
130
AIを「創る」と「使う」の循環 — HRテックが実践するリアルなAI組織実装
taketo957
0
1.7k
Snowflakeと仲良くなる第一歩
coco_se
1
120
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
2026.06.13_AI時代に事業会社が「SIer出身エンジニア」を求める理由 / Why Businesses Seek Engineers with a System Integrator Background in the AI Era
jumtech
0
890
AIにフローを作らせようとして挫折した話
hamatsutaichi
0
220
React、まだ楽しくて草
uhyo
7
4.2k
AI Testing Talks: Challenges of Applying AI in Software Testing: From Hype to Practical Use
exactpro
PRO
1
140
Ruby::Boxでできること、Refinementsでできること
joker1007
3
400
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
1
530
AIプラットフォームを運用し続けるための可観測性
tanimuyk
4
1.2k
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
300
Crafting Experiences
bethany
1
170
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
460
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
140
Producing Creativity
orderedlist
PRO
348
40k
Transcript
0LJUDWLQJWR -8QLW -RDQQD+X
About the Speaker Joanna Hu • Backend Engineer • Working
in LINE Taiwan since 2019
01 02 03 Summary :KDWLV-8QLW :K\PLJUDWLQJWR-8QLW +RZWRPLJUDWHWR-8QLW
:KDWLV-8QLW • -8QLW-XSLWHUWKHQHZSURJUDPPLQJH[WHQVLRQPRGHOIRUZULWLQJWHVWVDQGH[WHQVLRQVLQ-8QLW • -8QLW9LQWDJH 7HVW(QJLQH IRUUXQQLQJ-8QLWDQG-8QLWEDVHGWHVWVRQWKHSODWIRUP • -8QLW3ODWIRUP IRXQGDWLRQIRUODXQFKLQJWHVWLQJIUDPHZRUNVRQWKH-90
※Source from︓https://dzone.com/articles/7-reasons-to-consider-junit-5
:K\PLJUDWLQJWR-8QLW • 6XSSRUWHGLQPDMRU,'(%XLOGWRROV • ,QWHOOLM ,'($(FOLSVH96&RGH • 0DYHQ*UDGOH • (DV\PLJUDWLRQ
• -8QLWWHVWVFDQFRH[LVWZLWK-8QLWWHVWV • :HFDQXVHERWK-8QLW$VVHUW- DVVHUWLRQVLQRQHWHVW • 1HZ)HDWXUHV
-8QLW1HZ)HDWXUHV • 1HVWHGWHVWV • 'LVSOD\QDPH • 3DUDPHWHUL]HGWHVWV • 0XOWLSOH5XQQHUV •
%HWWHU$VVHUWLRQV EXWZHUHFRPPHQG$VVHUW- LQVWHDG
1HVWHGWHVWV • #1HVWHGFDQKDYHPXOWLSOHOHYHOV • 6XSSRUWQRQVWDWLFLQQHUFODVV class TestingAStackDemo { Stack<Object> stack;
@Test void isInstantiatedWithNew() { new Stack<>(); } @Nested class WhenNew { @BeforeEach void createNewStack() { stack = new Stack<>(); } @Test void isEmpty() { assertTrue(stack.isEmpty()); } @Test void throwsExceptionWhenPopped() { assertThrows(EmptyStackException.class, stack::pop); } @Nested class AfterPushing { // more tests... } } }
1HVWHGWHVWV
'LVSOD\QDPHV • $GG#'LVSOD\1DPH DQQRWDWLRQ • 6XSSRUWDGGLQJRQFODVVPHWKRG @DisplayName("A stack") class TestingAStackDemo
{ Stack<Object> stack; @Test @DisplayName("is instantiated with new Stack()") void isInstantiatedWithNew() { new Stack<>(); } @Nested @DisplayName("when new") class WhenNew { @BeforeEach void createNewStack() { stack = new Stack<>(); } @Test @DisplayName("is empty") void isEmpty() { assertTrue(stack.isEmpty()); } @Nested @DisplayName("after pushing an element") class AfterPushing { // more tests... } } }
'LVSOD\QDPHV • $GG#'LVSOD\1DPH DQQRWDWLRQ • 6XSSRUWDGGLQJRQFODVVPHWKRG
3DUDPHWHUL]HGWHVWV -8QLW class CalculatorJUnit5Test { @ParameterizedTest @ValueSource(strings = { "",
" ", " " }) void isBlank_ShouldReturnTrueForBlankStrings(String input) { assertThat(StringUtils.isBlank(input)).isTrue(); } @ParameterizedTest @NullSource void isBlank_ShouldReturnTrueForNullStrings(String input) { assertThat(StringUtils.isBlank(input)).isTrue(); } @ParameterizedTest @CsvSource({ "0,0,0", "1,1,2" }) void add(int first, int second, int expected) { final Calculator calculator = new Calculator(); final int result = calculator.add(first, second); assertThat(result).isEqualTo(expected); } }
0XOWLSOH5XQQHUV -8QLWRQO\VXSSRUWVVLQJOHUXQQHUZKLOH-8QLWVXSSRUWVPXOWLSOHH[WHQVLRQV // JUnit 4 @RunWith(MockitoJUnitRunner.class) public class CMSProductServiceTest {
// ... } // JUnit 5 @ExtendWith({ MockitoExtension.class, SoftAssertionsExtension.class }) public class CMSProductServiceTest { // ... }
+RZWRPLJUDWHWR-8QLW • 8SJUDGHWR-8QLWLQ0DYHQ*UDGOH • 8SJUDGH0DYHQWR 2U0DYHQVXUHILUHIDLOVDIHSOXJLQWR • 8SJUDGH*UDGOHWR • :ULWHQHZWHVWVLQ-8QLW
• 0LJUDWHH[LVWLQJ-8QLWWHVWV • 5HZULWH-8QLW5XOHWR-8QLW([WHQVLRQ LIDQ\
0LJUDWHH[LVWLQJ-8QLWWHVWV JUnit 4 JUnit 5 org.junit.Test org.junit.jupiter.api.Test org.junit.Before org.junit.jupiter.api.BeforeEach org.junit.After
org.junit.jupiter.api.AfterEach org.junit.BeforeClass org.junit.jupiter.api.BeforeAll org.junit.AfterClass org.junit.jupiter.api.AfterAll org.junit.Ignore org.junit.jupiter.api.Disabled org.junit.Assert org.junit.jupiter.api.Assertions (we use AssertJ) org.junit.Assert.assertThat org.hamcrest.MatcherAssert.assertThat org.junit.runner.RunWith org.junit.jupiter.api.extension.ExtendWith org.mockito.junit.MockitoJUnitRunner org.mockito.junit.jupiter.MockitoExtension org.springframework.test.context.junit4.SpringRu nner org.springframework.test.context.junit.jupiter.Spri ngExtension
5HZULWH-8QLW5XOHWR-8QLW([WHQVLRQ -8QLW5XOH public class EmbeddedMySqlRule extends ExternalResource { private EmbeddedMysql
embeddedMysql; @Override protected void before() { // ... embeddedMysql = EmbeddedMysql.anEmbeddedMysql(config, downloadConfig) .addSchema("ecac", ScriptResolver.classPathScript("db/setup.sql")) .start(); } @Override protected void after() { if (embeddedMysql != null) { embeddedMysql.stop(); } } }
5HZULWH-8QLW5XOHWR-8QLW([WHQVLRQ -8QLW([WHQVLRQ public class EmbeddedMySqlExtension implements AfterAllCallback, BeforeAllCallback { private
EmbeddedMysql embeddedMysql; @Override public void beforeAll(ExtensionContext extensionContext) throws Exception { // ... embeddedMysql = EmbeddedMysql.anEmbeddedMysql(config, downloadConfig) .addSchema("ecac", ScriptResolver.classPathScript("db/setup.sql")) .start(); } @Override public void afterAll(ExtensionContext extensionContext) throws Exception { if (embeddedMysql != null) { embeddedMysql.stop(); } } }
0LJUDWH8VLQJ,QWHOOL-,'($ 0LJUDWHRQHWHVW 0LJUDWHDOOWHVWV 5HIDFWRU!0LJUDWH https://blog.jetbrains.com/idea/2020/08/migrating-from-junit-4-to-junit-5/
• -8QLWZHEVLWHhttps://junit.org/junit5/ • 5HDVRQVWR&RQVLGHU-8QLWhttps://dzone.com/articles/7-reasons-to-consider-junit-5 • 0LJUDWLQJIURP-8QLWWR-8QLWhttps://blog.jetbrains.com/idea/2020/08/migrating-from-junit-4-to-junit-5/ 5HIHUHQFHV
THANK YOU