현재노트
asserts-core, junit-jupiter 를 활용한 단위테스트 본문
테스트는 테스트 대상 범위나 성격에 때라 E2E 테스트, Integration Test(통합 테스트), Unit Test(단위 테스트) 등 3가지로 구분합니다.
현재 여기 페이지에서는 단위 테스트에 대해서 설명을 할것입니다.
단위테스트는 클래스 범주 내에서 작은 단위(함수 단위)의 기능에 대한 유효성을 검증하는 테스트입니다.
매우 간단하고 명확하며 빠르게 실행된다는 특징이 있습니다.
본 문서는 asserts-core, junit-jupiter를 사용하여 테스트 코드를 작성하였습니다.
dependencies {
testImplementation 'org.assertj:assertj-core:3.22.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
}
테스트 코드에 사용할 코드는 Operator 라는 enum만 사용하여 예시를 만들도록 하겠습니다.
기능은 연산이 가능한 계산기 프로그램입니다.
import java.util.Arrays;
import java.util.function.ToIntBiFunction;
public enum Operator {
PLUS("+", (a,b) -> a + b),
MINUS("-", (a,b) -> a - b ),
MULTIPLY("*", (a,b) -> a * b),
DIVIDE("/", (a,b) -> {
if(b == 0) {
throw new RuntimeException("0으로 나눌수 없습니다.");
}
return a / b;
});
private final String symbol;
private final ToIntBiFunction<Integer, Integer> operate;
Operator(String symbol, ToIntBiFunction<Integer, Integer> operate) {
this.symbol = symbol;
this.operate = operate;
}
public int operate(int a, int b) {
return operate.applyAsInt(a, b);
}
public static Integer operate(String symbol, int a, int b) {
return Arrays.stream(values())
.filter(it -> it.symbol.equals(symbol))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("없는 심볼입니다..."))
.operate(a, b);
}
}
테스트코드는 일반적으로 @DisplayName으로 어떤 테스트를 하는지를 작성을 하며, assertThat을 사용하여 원하는 결과를 확인합니다.
import static org.assertj.core.api.Assertions.assertThat;
class OperatorTest {
@DisplayName("두개의 합이 2로 반환한다.")
@Test
void plus() {
int result = Operator.operate("+", 1, 1);
assertThat(result).isEqualTo(2);
}
}
인텔리제이 기준으로 테스트를 실행후, 실행 결과를 확인할 수 있습니다.
만약 원하는 결과 값과 실행결과가 다를 경우, Tests failed 가 뜨고, 실패한 이유가 콘솔로 보여주게 됩니다.
테스트 코드에는 원하는 결과값을 원하는 경우도 있지만 에러를 테스트하는 경우도 있다.
위에 예제에서 +, -, *, / 네개의 연산자 말고 다른 경우가 입력이 되게 된다면 에러를 반환한다.
이것도 테스트 코드에서 테스트가 가능하다.
@DisplayName("존재하지 않는 연산자일 경우 에러를 반환한다.")
@Test
void operatorException() {
assertThatThrownBy(() -> Operator.operate("@", 1, 1))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("없는 심볼입니다...");
}
assertThatThrownBy로 에러가 발생할 메소드를 넣으면 InstanceOf 정의된 에러가 맞다면, 테스트는 성공으로 표시가 된다.
또한, 자주 에러가나는 IllegalArgumentException이나 IoException같은 경우는 정의 된 메소드가 있어 편하게 에러를 검증할 수 있다.
@DisplayName("존재하지 않는 연산자일 경우 에러를 반환한다.")
@Test
void operatorException2() {
assertThatIllegalArgumentException().isThrownBy(() -> {
Operator.operate("@", 1, 1);
}).withMessage("없는 심볼입니다...");
}
만약에 +, -, *, / 를 모두 테스트하고 싶으면 어떻게 할까?
모든 메소드를 넣고 검증을 하면 되는걸까? 그럴경우에는 중복되게 사용되는 코드들이 생겨나 코드를 이해하는데도 어려움이 생길 여지가 충분히 있다.
그래서 junit-jupiter-parameters 라는 라이브러리에서는 @ParameterizedTest를 사용하여 반복하여 테스트를 할 수 있게 도움을 주고 있다.
methodSource는 입력값들을 메소드에 정의시켜 입력값을 넣어주는 역할을 하고 있다.
이렇게 되면 사칙연산을 한번에 모두 테스트를 할 수 있어 테스트 코드 작성하는데 시간을 줄일 수 있다.
@ParameterizedTest
@MethodSource("parameters")
void operate(int a, String symbol, int b, int expected) {
int result = Operator.operate(symbol, a, b);
assertThat(result).isEqualTo(expected);
}
private static Stream<Arguments> parameters() {
return Stream.of(
arguments(1, "+", 1, 2),
arguments(2, "-", 1, 1),
arguments(3, "*", 4, 12),
arguments(4, "/", 2, 2)
);
}
'Back > testCode' 카테고리의 다른 글
API Controller를 테스트하는 E2E 테스트 (0) | 2023.06.13 |
---|---|
Respository나 Service단 로직을 검증하는 통합테스트 (0) | 2023.06.09 |