프로그램을 작은 단위들로 쪼개서 해당 기능들이 올바르게 작동하는지 테스트를 하는 것이 단위테스트. 단위테스트를 지원하는 프레임워크 중 유명한 것이 JUnit5.
Test 메서드임을 나타내기 위한 어노테이션. 이걸 붙여야만 테스트 메서드로 인식한다.
테스트 메서드는 무조건 void 메서드여야 한다.
중첩 클래스 내부에 있다는 것을 알리기 위한 어노테이션.
테스트가 실행되지 않는다.
assertEquals()의 인자로 사용자가 정의한 오브젝트를 넣어주려고 할 때,
equals()가 해당 클래스에 정의되어 있지 않으면 오류가 난다.
따라서 equals()가 해당 클래스에 오버로딩 되어 있어야 한다.
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LocalObject that = (LocalObject) o;
return value == that.value;
}
이거 그냥 인텔리제이에서 자동으로 생성해주는 거였다. cmd+n 누르고 equals() and hashCode() 누르면 됨
챗지피티에선
// 주어진 객체가 MyClass의 인스턴스인지 확인
if (!(obj instanceof MyClass)) {
return false;
}
를 사용하라고 했었는데
instanceOf
는 컴파일 시점에 작동하고 getClass()
는 런타임 시점에 작동함. 따라서 정적으로 클래스가 결정된 경우에나 instanceOf
을 사용할 수 있는 거고, 동적으로 결정되는 경우에는 getClass()
로 비교를 해주어야 함.
두 값이 다르다면 테스트를 성공시킨다.
두 객체가 같으면 테스트를 성공시킨다.
assertThrows(Exception.class, this::causeException);
이런식으로 사용
아니면 람다식으로 사용할 수도 있음
assertThrows(ArithmeticException.class, () -> {
int result = 10 / 0; // 0으로 나누는 연산을 수행하면 ArithmeticException이 발생함
});
assertDoesNotThrow(() -> {
final var number = Integer.valueOf(0x80000000);
});
assertAll(
() -> assertEquals(3, 1 + 2),
() -> assertEquals(5, 3 + 2),
() -> assertEquals(21, 7 * 3),
() -> assertEquals(32, 3 * 7 ^ 5),
() -> assertEquals(4, 7 * 3 / 5 + 33 / 21),
() -> assertEquals(22, 33 * 3 / 5 + 7 / 2),
() -> assertEquals(22, 33 * 3 / 5 + 7 / 2 + 1)
);
assertAll()
을 사용하지 않으면 차례대로 코드가 진행되다가 throw가 되면 거기서 멈춘다. 하지만 사용하면 끝까지 진행하고 몇 개의 실패가 있었는지 Multiple Failures로 알려준다.
인자를 제공하는 테스트.
보통 테스트에 따라 @ValueSource
와 @MethodSource
같은 어노테이션 중 적합한 어노테이션을 선택하여 테스트를 진행할 수 있다.
public class MyTest {
@ParameterizedTest
@ValueSource(strings = {"apple", "banana", "orange"})
public void testStringNotEmpty(String value) {
assertTrue(value.length() > 0);
}
}
한 메서드를 가지고 여러 테스트를 진행해보고 싶을 때 @ValueSource를 사용해서 매개변수를 간단하게 지정해줄 수 있다. ints, strings, doubles, classes 등을 사용할 수 있다.
이는 함수의 인자에 하나씩 들어가서 실행되게 된다.
이 때 ValueSource의 타입과 함수 인자의 타입이 다르면 자동 형변환이 일어나게 된다.
이건 단순한 변수가 아니라 메서드를 전달해주고 싶을 때.
public class ExampleTest {
@ParameterizedTest
@MethodSource("provideArguments")
void testWithArguments(int expected, int input) {
assertEquals(expected, input * input);
}
static Stream<Arguments> provideArguments() {
return Stream.of(
Arguments.arguments(4, 2),
Arguments.arguments(9, 3),
Arguments.arguments(16, 4)
);
}
}