
1. 개발 환경 Setting
Gradle Dependency
plugins {
java
}
dependencies {
testImplementation('junit:junit:4.13')
}
- Junit4를 사용하기 위해 build.gradle에 위의 라인을 추가합니다.
Make Test Class

- Test 하고자 하는 class 이름 오른쪽 클릭 → Go To → Test (Ctrl+Shift+T) → Test

- Create Test → public, protected Method 만 보입니다.
2. JUnit 단위 테스트 작성 Example
JUnit Test
originalText를 STimestamp라는 포맷으로 변환해주는 클래스입니다. convertFormat()이라는 함수가 보이시나요? 개발자가 의도한 행동을 수행하는지 테스트해봐야 할 것 같은 느낌이 듭니다.
- YearMonthDay가 하는 일 : "String → STimestamp" based on UTC
public class YearMonthDay implements Converter {
private final String originalText;
private final String zoneId;
public YearMonthDay(String zoneId, String originalText) {
this.zoneId = zoneId;
this.originalText = originalText;
}
@Override
public STimestamp convertFormat() {
String yearMonthDayFormat = DateTimeFormat.YEARMONTHDAY.getFormat();
LocalDate localDate = LocalDate
.parse(originalText, DateTimeFormatter.ofPattern(yearMonthDayFormat));
ZonedDateTime zonedDateTimeOf = ZonedDateTime.of(localDate.atStartOfDay(), ZoneId.of(zoneId));
ZonedDateTime zonedDateTime = zonedDateTimeOf.withZoneSameInstant(ZoneId.of("UTC"));
STimestamp result = new STimestamp();
result.setTimestamp(Timestamp.valueOf(zonedDateTime.toLocalDateTime()));
return result;
}
}
3가지 정도를 Test 하면 함수에 대한 확신을 얻을 수 있을 것 같습니다.
- zoneId가 Seoul일 때 UTC로 잘 변환해주는지!
- zoneId가 UTC일 때 그대로 UTC로 반환해주는지!
- format이 맞지 않는 String을 변환하려 할 때 의도한 오류가 검출되는지!
- Test 전 setUp
public class YearMonthDayTest {
private String yyyyMMdd;
@Before
public void setUp() {
yyyyMMdd = "2020.05.13";
}
@Rule
public ExpectedException thrown = ExpectedException.none();
...
}
- @Before 어노테이션을 통해 각 @Test 전 수행하는 기본값을 만들어줍니다.
- @Rule 어노테이션을 통해 Exception을 직접 확인합니다.
@Rule
- Rule은 테스트 클래스에서 동작 방식을 재정의 하거나 쉽게 추가하는 것을 가능하게 합니다.
- 사용자는 기존의 Rule을 재사용하거나 확장하는 것이 가능합니다.
ExpectedException
- 예외를 직접 확인할 수 있습니다.
- Error 메시지도 검증이 가능합니다.
- zoneId가 Seoul일 때 UTC로 잘 변환해주는지 Test
@Test
public void convertFormat_Generates_UTC_STimestamp_If_ZoneId_Is_Seoul_Test() {
//given
String zoneIdSeoul = "Asia/Seoul";
YearMonthDay yearMonthDaySeoul = new YearMonthDay(zoneIdSeoul, yyyyMMdd);
Timestamp expected = Timestamp.valueOf("2020-05-12 15:00:00"); //24-9 = 15(UTC)
//when
Timestamp actual = yearMonthDaySeoul.convertFormat().getTimestamp();
//then
assertThat(actual, is(expected));
}
zoneId가 Seoul인 서버에서 받은 값 “2020.05.13”의 UTC값은 9시간을 뺀 “2020-05-12 15:00:00”입니다. 함수가 의도한 대로 9시간을 빼는 행동을 수행하는지 확인합니다.
- zoneId가 UTC일 때 그대로 UTC 반환하는지 Test
@Test
public void convertFormat_Generates_UTC_STimestamp_When_ZoneId_Is_UTC_Test() {
//given
String zoneIdUTC = "UTC";
YearMonthDay yearMonthDayUTC = new YearMonthDay(zoneIdUTC, yyyyMMdd);
Timestamp expected = Timestamp.valueOf("2020-05-13 00:00:00");
//when
Timestamp result = yearMonthDayUTC.convertFormat().getTimestamp();
//then
assertThat(result, is(expected));
}
zoneId가 UTC인 서버에서 받은 값 “2020.05.13”은 함수가 의도한 대로 “2020-05-13 00:00:00으로 변환하는 행동을 수행하는지 확인합니다.
- format이 맞지 않는 String을 변환하려 할 때 적절한 오류가 검출되는지 Test
@Test
public void convertFormat_Generates_Exception_If_Unexpected_Format_Test() {
thrown.expect(DateTimeParseException.class);
String unexpectedText = "unexpectedFormat";
YearMonthDay yearMonthDayFail = new YearMonthDay("UTC", unexpectedText);
yearMonthDayFail.convertFormat();
}
예상한 Format이 아닐 때 DateTimeParseException을 던지는지 확인합니다.
3. Hamcrest
가독성 있는 Test를 만들기 위해 Hamcrest 사용을 추천합니다. Hamcrest는 다양한 조건의 Match rule을 쉽게 작성하고, 테스트할 수 있는 라이브러리입니다.
assertEquals(actual, expected)
assertThat(actual, is(expected))
위의 두 문장 중 가독성 측면에서 Hamcrest ‘is’를 사용한 아래쪽 문장이 더 가독성이 높습니다.
(더 많은 Matchers : http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html)
FailTest실행결과

또한, assertEquals와 달리 assertThat은 expected 값과 actual 값 모두 에러 메시지에 반환됩니다. 원인을 찾기 위해 별도의 디버깅 필요 없이 에러 메시지 만으로 잘못된 부분을 바로 파악할 수 있습니다.
4. Summary
Test 하고 싶은 행동을 정의합니다.
그 결과를 예상합니다.
예상 결과와 실제 함수의 return값을 비교합니다.
예상한 오류(Exception)인지 확인합니다.
Tip
- given → when → then에 맞춰 작성하는 것이 좋습니다.
- assert문은 한 test함수에 하나면 충분합니다.
- verify로 수행 횟수를 체크할 수 있습니다.
'Spring' 카테고리의 다른 글
[DSC-Sookmyung] Spring Boot Core Member 팁 - Week 1&2(0) | 2020.10.19 |
---|---|
[Spring Boot] Spring Boot란? Spring Boot의 특징과 장점(0) | 2020.10.04 |
Test 2편 - Mockito Test Framework 알아보기(0) | 2020.10.04 |