[Java] 테스트 코드(Junit5, AssertJ) - 2

수박이삼촌·2024년 3월 16일
0

Java

목록 보기
21/21
post-thumbnail

실습한 코드는 깃허브 링크에서 확인 가능하십니다.

이전 블로그 포스트에 이어서 적어보겠습니다.

이번엔 예시들을 생성해 JUnit5(Jupiter)에서 사용되는 다양한 테스트 코드 메소드를 작성해보겠습니다.

0. 🐳 실습 준비

Calculator

두 정수를 더해주는 계산기 메소드를 가진 Calculator 클래스를 생성해주겠습니다.

public class Calculator {

    public int plusTwoNumbers(int firstNum, int secondNum) {

        return firstNum + secondNum;
    }
}

Person

String 값의 비교를 위해 Person 클래스도 생성해줍니다.

public class Person {

    private final String firstName;
    private final String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }
}

PositiveNumberValidator

예외 처리 테스트를 위해 valid를 체크할 수 있는 PositiveNumberValidator 클래스를 생성해주겠습니다.

public class PositiveNumberValidator {

    public void checkDividableNumbers(int firstNum, int secondNum) {

        if (secondNum == 0) {
            throw new IllegalArgumentException("0으로 나눌 수 없습니다.");
        }

    }

}

1. 🐳 JUnit5(Jupiter)

JUnit Jupitersms JUnit4로부터 온 assertion 메소드와 새롭게 자바 8 람다 표현식으로 추가된 메소드를 제공합니다.

모든 Jupiter Assertions의 메소드는 정적(static) 메소드 형태로 제공하고 있습니다.

1-1. 🐬 사용 패턴

테스트 코드를 작성할 때 가장 많이 사용하는 패턴은 given / when / then 패턴입니다.

  • given : 테스트 시 필요한 파라미터를 준비합니다.
  • when : 테스트를 할 메소드를 호출합니다.
  • then : 실행 결과를 검증합니다.

단, 하나의 테스트 메소드에는 한 가지를 검증할 수 있도록 작성하는 것이 좋습니다.
간혹 테스트할 메소드의 검증을 동시에 진행하는 경우도 존재합니다. (when & then)

1-2. 🐬 assertEquals()

assertEquals(expected, actual) 메소드는 실제 값과 기대 값의 일치 여부를 동일성으로 판단합니다.

given

        int firstNum = 10;
        int secondNum = 20;
        int expected = 30;
        int expectedDelta = 28;

when

src/main/java에 동일한 패키지 위치에 Calculator 클래스를 만들어서 테스트합니다.

        Calculator calculator = new Calculator();
        int result = calculator.plusTwoNumber(firstNum, secondNum);

then

기본

Assertions.assertEquals(result, expected);

허용할 오차 범위

// 세 번째 인자는 delta라고 불리는데, 이는 허용할 오차 범위를 의미합니다

Assertions.assertEquals(expectedDelta, result, 1);	// 실패
Assertions.assertEquals(expected, result, 1);	// 성공

실패 시 메세지

/* 설명. 세 번째 인자는 문자열로 테스트 실패 시 보여줄 메세지를 작성할 수 있습니다. */
Assertions.assertEquals(expectedDelta, result, "실패할 때 보여줄 메세지"); // 실패
Assertions.assertEquals(expected, result, "실패할 때 보여줄 메세지");   // 성공

람다 이용

/* 설명. 람다를 이용해도 결과는 동일하지만 불필요한 경우 메세지를 만들지 않도록 지연로딩을 이용합니다. */
Assertions.assertEquals(expectedDelta, result, () -> "실패할 때 보여줄 메세지");    // 실패
Assertions.assertEquals(expected, result, () -> "실패할 때 보여줄 메세지");

실패 시 결과


1-3. 🐬 assertNull()

assertNull(actual) 메소드는 래퍼런스 변수가 null 값을 가지는 지를 판단합니다.

given

String str;

when

str = null;

then

Assertions.assertNull(str);

1-4. 🐬 assertTrue()

assertTrue(actual) 메소드는 결과값이 true인지를 확인합니다.

given

int num1 = 10;
int num2 = 10;

when

boolean result = num1 == num2; // true

then

Assertions.assertTrue(result);

/* assertEquals로 true값과 일치하는지를 확인하는 기능과 동일합니다 */
Assertions.assertEquals(true, result);

1-5. 🐬 assertFalse()

assertFalse(actual) 메소드는 결과값이 false인지 확인합니다

given

int num1 = 10;
int num2 = 20;

when

boolean result = num1 == num2;

then

Assertions.assertFalse(result);

1-6. 🐬 assertAll()

assertAll(Exeutable...) 모든 Assertion이 실행되고 실패가 함께 보고되는 그룹화된 Assertion 입니다.

given

String firstName = "길동";
String lastName = "홍";

when

Person person = new Person(firstName, lastName);

then

Assertions.assertAll(
                "그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐)",
                () -> Assertions.assertEquals(firstName, person.getFirstName(), () -> "firstName이 잘못됨"),
                () -> Assertions.assertEquals(lastName, person.getLastName(), () -> "lastName이 잘못됨")
        );

한 개라도 테스트 실패 시, "그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐)"이 각 Assertions의 실패 메세지와 함꼐 출력됩니다.

org.opentest4j.MultipleFailuresError: 그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐) (1 failure)

firstName이 잘못됨
Expected :길동i
Actual   :길동

1-7. 🐬 assertInstanceOf()

인스턴스 타입을 검증해주는 테스트입니다.

given

String firstName = "길동";
String lastName = "홍";

when

Person person = new Person(firstName, lastName);

then

Assertions.assertInstanceOf(Person.class, person);

1-8. 🐬 assertDoesNotThrow()

assertDoesNotThrow(excutable) 메소드 호출 시 아무런 예외가 발생하지 않는지 확인해줍니다.

given

int firstNum = 10;
int secondNum = 3;

when & then

PositiveNumberValidator validator = new PositiveNumberValidator();
Assertions.assertDoesNotThrow(
	() -> validator.checkDividableNumbers(firstNum, secondNum)
 );

1-9. 🐬 assertThrow()

assertThrows(Class, excutable) 메소드 호출 시 특정한 예외가 발생하는 지 확인해줍니다.

given

int firstNum = 10;
int secondNum = 0;
String expectedErrorMessage = "0으로 나눌 수 없습니다.";

when

Exception exception = Assertions.assertThrows(
	Exception.class,
    () -> validator.checkDividableNumbers(firstNum, secondNum)
);

then

Assertions.assertAll(
	() -> Assertions.assertInstanceOf(IllegalArgumentException.class, exception, () -> "예외 타입이 일치하지 않습니다."),
    () -> Assertions.assertEquals(expectedErrorMessage, exception.getMessage(), () -> "예외 메세지가 일치하지 않습니다.")
);

1-10. 🐬 assertLinesMatch()

assertLinesMatch(list, list) 두 개의 문자열 목록이 같은 지 확인해줍니다.(문자열만 가능합니다.)

given

List<String> expected = Arrays.asList("java", "database", "spring");

when

List<String> actual = Arrays.asList("java", "database", "spring");

then

Assertions.assertLinesMatch(expected, actual, () -> "두 리스트의 값이 일치하지 않습니다.");
profile
Today I Learned

0개의 댓글