개발 등/SPRING

JUnitParams (도메인 테스트에 매개변수 이용)

darkhorizon 2023. 4. 28. 17:07
728x90
반응형

JUnit을 사용해서 테스트를 진행하면 매개변수를 사용할 수가 없다.

그런데 도메인 단위의 테스트를 진행하다 보면 같은 코드에 매개변수만 달리하는 중복된 코드가 발생하는 경우가 종종 있다.

이럴 경우 JUnitParams 를 사용하면 매개변수를 이용할 수 있어서 테스트 코드가 훨씬 간결해진다.

 

사용법은 JUnit4와 JUnit5에 따라 다르다.

 

1. JUnit4

 

다음과 같이 의존성을 추가한다.

Maven

<dependency>
  <groupId>pl.pragmatists</groupId>
  <artifactId>JUnitParams</artifactId>
  <version>1.1.1</version>
  <scope>test</scope>
</dependency>

Gradle

testCompile 'pl.pragmatists:JUnitParams:1.1.1'

 

다음과 같이 테스트 코드를 작성하면 된다.

@RunWith(JUnitParamsRunner.class)
public class PersonTest {

  @Test
  @Parameters({"17, false", 
               "0, true" })
  void testFree(int basePrice, boolean isFree) {
  	Event event = Event.builder()
    				.basePrice(basePrice)
                    .build();
    assertThat(event.isFree()).isEqualsTo(isFree);
  }
  
  //위의 경우엔 파라미터가 타입세이프하지 않으므로 다음과 같이 작성하는 편이 훨씬 좋은 코드
  @Test
  @Parameters(method = "parametersForTestFreeSafe")
  void testFreeTypeSafe(int basePrice, boolean isFree) {
    Event event = Event.builder()
    				.basePrice(basePrice)
                    .build();
    assertThat(event.isFree()).isEqualsTo(isFree);
  }
  
  private Object[] parametersForTestFreeSafe() {
  	return new Object[] {
    	new Object[] {17, false},
        new Object[] {0, true}
    };
  }
  
}

# 참고로 위에서 testFreeTypeSafe메서드가 참조하는  private Object[] parametersForTestFreeSafe() 메서드에서

하일라이트된 parametersFor 가 JUnitParams에서 제공하는 편의기능 prefix로 이후 나오는 메서드명을 유추하여 실행하도록 한다.

예를 들어 parametersForTestFreeSafe의 경우, 편의기능 prefix인 parametersFor 를 제외한 메서드명인 testFreeSafe() 메서드가 실행될 때 해당 참조 메서드가 실행된다. 따라서 위의 testFreeTypeSafe의 @Parameters 어노테이션에 method 값을 생략해도 된다. 

 

2. JUnit5

다음과 같이 의존성을 추가한다.

 Maven
 
	<dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-params</artifactId>
        <version>5.9.2</version>
        <scope>test</scope>
    </dependency>
    
Gradle
	testCompile 'org.junit.jupiter:junit-jupiter-params:5.9.2'

테스트 코드가 JUnit4와 달라진 점은

  - 클래스 레벨의 @RunWith(JUnitParamsRunner.class) 어노테이션 삭제

  - 메서드 레벨의 @Test 가 @ParameterizedTest 로 대체

  - 메서드 레벨의 @Parameters 가 @CsvSource, @MethodSource 등으로 대체

  - @MethodSource의 참조 메서드는 테스트를 진행할 때 이미 메모리에 올라가 있어야 하기 때문에 static으로 선언

테스트 코드 예제는 다음과 같다.

@ParameterizedTest
@CsvSource({
        "0, 0, true",
        "0, 100, false",
        "100, 0, false",
})
public void testFree(int basePrice, int maxPrice, boolean isFree) {
    Event event = Event.builder()
            .basePrice(basePrice)
            .maxPrice(maxPrice)
            .build();

    event.update();

    assertThat(event.isFree()).isEqualTo(isFree);
}

@ParameterizedTest
@MethodSource("isOffline")
public void testOffline(String location, boolean isOffline) {
    Event event = Event.builder()
            .location(location)
            .build();

    event.update();

    assertThat(event.isOffline()).isEqualTo(isOffline);
}

private static Stream<Arguments> isOffline() {
    return Stream.of(
            Arguments.of("강남역", true),
            Arguments.of(null, false),
            Arguments.of("", false)
    );
}

 

 

 

https://github.com/Pragmatists/JUnitParams

 

GitHub - Pragmatists/JUnitParams: Parameterised tests that don't suck

Parameterised tests that don't suck. Contribute to Pragmatists/JUnitParams development by creating an account on GitHub.

github.com

 

728x90