- Test Fixture 의 이해를 위한 글입니다.
- Test Fixtures 개념을 실제로 사용하는 2가지 방법을 다룹니다.
- 코드는 ⚙️ Github 에 있습니당!!
Test Fixture 란
일종의 개념이라고 생각합니다. 중복 발생되는 무언가(행위)를 고정시켜 한곳에 관리하도록 하겠다는 개념.
Test Fixture 를 사용 예시
금액과 나라를 가지고있는 Money 객체가 있다고 해봅니다.
@Getter
@AllArgsConstructor
@EqualsAndHashCode
public class Money {
private int money;
private String country;
/** 돈 더하기 **/
public Money add(Money anotherMoney) {
checkOrigin(anotherMoney.getCountry());
money+= anotherMoney.getMoney();
return new Money(money, country);
}
/** 나라 비교하기 **/
private void checkOrigin(final String country) {
if (!country.equals(country)) {
throw new NullPointerException("같은 나라 돈이 아니에여!");
}
}
}
이제 Money 객체를 테스트합니다
@Test
public void simpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
Assertions.assertThat(expected).isEqualTo(result);
}
이와 같은 상황에서, 다른 테스트를 진행한다고할 때, 아래처럼 똑같은 Money 객체를 매번 생성해야하는 상황이 생기겠죠??
@Test
public void simpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
Assertions.assertThat(expected).isEqualTo(result);
}
//예시를 위해 위와 같은 테스트지만,, 그냥 중복 발생된 다른 테스트 예제라고 생각해주세요ㅎㅎ
@Test
public void anotherAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money 다른비교객체= new Money(26, "CHF");
Money 다른테스트결과= m12CHF.add(m14CHF);
Assertions.assertThat(다른비교객체).isEqualTo(다른테스트결과);
}
Junit 에서는 이러한 상황, 즉 "동일하거나 유사한 개체 집합에 대해 작동하는 두 개 이상의 테스트가 있는경우" 테스트 픽스쳐를 사용하라고 권유합니다.
🙌🏻 Test Fixture 메소드 사용
위와같은 상황에서는 중복된 객체를 사전에 미리 정의해서 고정해두는 방식으로 픽스쳐를 구성할 수 있습니다.
private Money f12CHF_fixture;
private Money f14CHF_fixture;
private Money f28USD_fixture;
@BeforeAll
public void setUp() {
f12CHF_fixture= new Money(12, "CHF");
f14CHF_fixture= new Money(14, "CHF");
f28USD_fixture= new Money(28, "USD");
}
junit 에서는 이러한 기능의 픽스쳐 메소드를 제공합니다.
Annotation | Description |
@BeforeAll | 테스트 메소드 시작 전 1번 실행 |
@AfterAll | 테스트 메서드 종료 후 1번 실행 |
@BeforeEach | 각 테스트 메소드 시작 전 실행 |
@AfterEach | 각 테스트 메소드 종료 후 실행 |
개념이기 때문에 Fixture를 구성하는 방법은 다양하다고 생각합니다.
junit4 공식문서에서 말하는 fixture 는 테스트 픽스처 메소드를 사용하라고 합니다.
👏🏻 Test Fixtures 를 구성하는 다른 방법
이 개념을 토대로 코틀린에서 Fixture 라는 파일에 많은 생성자 케이스를 만들어 별도로 테스트에서 사용하는 객체의 생성을 관리하는 픽스쳐를 사용하는 우아한 테크 코스 깃허브 레포지토리입니다.
https://github.com/woowacourse/service-apply/blob/master/src/test/kotlin/apply/JudgmentFixtures.kt
우아한 테크코스 레포지토리 경우 테스트 픽스쳐를, 객체의 생성자를 이용해서 객체가 생성될 경우를 미리 정의해두어서 세팅에 관련된 부분은 한 곳에서만 관리하고, 테스트에서는 가져다 쓰겠다,,!!
라는 의도가 담겨있다고 느껴졌습니다.
해당 예시의 코틀린 코드를 자바 코드로 변경하면 이런식으로 Test Fixtrues 를 구성해볼 수 있을거같습니다.
Fixtures
public class MoneyFixtures {
public static Money createMoney(final int money) {
return new Money(money, "default");
}
public static Money createMoney(final String country) {
return new Money(10000, country);
}
public static Money createMoney(final int money, final String country) {
return new Money(money, country);
}
}
Test
public class MoneyFixtureTest {
private Money m12CHF = MoneyFixtures.createMoney(12);
private Money m14CHF = MoneyFixtures.createMoney(14);
@Test
public void simpleAdd() {
Money expected = MoneyFixtures.createMoney(26);
Money result= m12CHF.add(m14CHF);
Assertions.assertThat(expected).isEqualTo(result);
}
}
테스트 픽스쳐는 개념일뿐 위의 2가지 방법이 정답인것은 아닙니다!
실제로 자바지기 박재성님께서는 2번째 방법인 별도의 Fixture를 관리하는 방법은 사용하지않고 그때마다 생성자를 만든다고 들었습니다.
📌 모든 선택은 유지보수가 편한 방법으로!!!
*참고
- junit cookbook 가이드 : https://junit.org/junit4/cookbook.html
- junit : https://yoon0120.tistory.com/43
'Spring > Test-Driven Develop' 카테고리의 다른 글
[Spring] service 단위 테스트 하기 - DB 와 독립된 테스트 환경 구축 (service unit test) (0) | 2023.01.13 |
---|---|
[Junit] @ParameterizedTest 객체에 값을 자동으로 넣어주는 Auto Param - @autosource (0) | 2022.12.27 |
[JUnit] JAVA 매개변수 Test - @ParameterizedTest (0) | 2022.09.29 |
[Spring] java private 메소드 테스트 코드 작성하기 (4) | 2022.08.24 |
[Spring] 백엔드 부하 테스트 해보기 - nGrinder(with aws, jmeter) (4) | 2022.03.14 |