실습한 코드는 깃허브 링크에서 확인 가능하십니다.
이전 블로그 포스트에 이어서 적어보겠습니다.
이번엔 예시들을 생성해 JUnit5(Jupiter)에서 사용되는 다양한 테스트 코드 메소드를 작성해보겠습니다.
두 정수를 더해주는 계산기 메소드를 가진 Calculator 클래스를 생성해주겠습니다.
public class Calculator {
public int plusTwoNumbers(int firstNum, int secondNum) {
return firstNum + secondNum;
}
}
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;
}
}
예외 처리 테스트를 위해 valid를 체크할 수 있는 PositiveNumberValidator 클래스를 생성해주겠습니다.
public class PositiveNumberValidator {
public void checkDividableNumbers(int firstNum, int secondNum) {
if (secondNum == 0) {
throw new IllegalArgumentException("0으로 나눌 수 없습니다.");
}
}
}
JUnit Jupitersms JUnit4로부터 온 assertion 메소드와 새롭게 자바 8 람다 표현식으로 추가된 메소드를 제공합니다.
모든 Jupiter Assertions의 메소드는 정적(static) 메소드 형태로 제공하고 있습니다.
테스트 코드를 작성할 때 가장 많이 사용하는 패턴은 given / when / then 패턴입니다.
단, 하나의 테스트 메소드에는 한 가지를 검증할 수 있도록 작성하는 것이 좋습니다.
간혹 테스트할 메소드의 검증을 동시에 진행하는 경우도 존재합니다. (when & then)
assertEquals(expected, actual) 메소드는 실제 값과 기대 값의 일치 여부를 동일성으로 판단합니다.
int firstNum = 10;
int secondNum = 20;
int expected = 30;
int expectedDelta = 28;
src/main/java에 동일한 패키지 위치에 Calculator 클래스를 만들어서 테스트합니다.
Calculator calculator = new Calculator();
int result = calculator.plusTwoNumber(firstNum, secondNum);
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, () -> "실패할 때 보여줄 메세지");
assertNull(actual) 메소드는 래퍼런스 변수가 null 값을 가지는 지를 판단합니다.
String str;
str = null;
Assertions.assertNull(str);
assertTrue(actual) 메소드는 결과값이 true인지를 확인합니다.
int num1 = 10;
int num2 = 10;
boolean result = num1 == num2; // true
Assertions.assertTrue(result);
/* assertEquals로 true값과 일치하는지를 확인하는 기능과 동일합니다 */
Assertions.assertEquals(true, result);
assertFalse(actual) 메소드는 결과값이 false인지 확인합니다
int num1 = 10;
int num2 = 20;
boolean result = num1 == num2;
Assertions.assertFalse(result);
assertAll(Exeutable...) 모든 Assertion이 실행되고 실패가 함께 보고되는 그룹화된 Assertion 입니다.
String firstName = "길동";
String lastName = "홍";
Person person = new Person(firstName, lastName);
Assertions.assertAll(
"그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐)",
() -> Assertions.assertEquals(firstName, person.getFirstName(), () -> "firstName이 잘못됨"),
() -> Assertions.assertEquals(lastName, person.getLastName(), () -> "lastName이 잘못됨")
);
한 개라도 테스트 실패 시, "그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐)"이 각 Assertions의 실패 메세지와 함꼐 출력됩니다.
org.opentest4j.MultipleFailuresError: 그룹화된 테스트 이름(한 개 이상의 테스트 실패 시 보여짐) (1 failure)
firstName이 잘못됨
Expected :길동i
Actual :길동
인스턴스 타입을 검증해주는 테스트입니다.
String firstName = "길동";
String lastName = "홍";
Person person = new Person(firstName, lastName);
Assertions.assertInstanceOf(Person.class, person);
assertDoesNotThrow(excutable) 메소드 호출 시 아무런 예외가 발생하지 않는지 확인해줍니다.
int firstNum = 10;
int secondNum = 3;
PositiveNumberValidator validator = new PositiveNumberValidator();
Assertions.assertDoesNotThrow(
() -> validator.checkDividableNumbers(firstNum, secondNum)
);
assertThrows(Class, excutable) 메소드 호출 시 특정한 예외가 발생하는 지 확인해줍니다.
int firstNum = 10;
int secondNum = 0;
String expectedErrorMessage = "0으로 나눌 수 없습니다.";
Exception exception = Assertions.assertThrows(
Exception.class,
() -> validator.checkDividableNumbers(firstNum, secondNum)
);
Assertions.assertAll(
() -> Assertions.assertInstanceOf(IllegalArgumentException.class, exception, () -> "예외 타입이 일치하지 않습니다."),
() -> Assertions.assertEquals(expectedErrorMessage, exception.getMessage(), () -> "예외 메세지가 일치하지 않습니다.")
);
assertLinesMatch(list, list) 두 개의 문자열 목록이 같은 지 확인해줍니다.(문자열만 가능합니다.)
List<String> expected = Arrays.asList("java", "database", "spring");
List<String> actual = Arrays.asList("java", "database", "spring");
Assertions.assertLinesMatch(expected, actual, () -> "두 리스트의 값이 일치하지 않습니다.");