728x90
반응형
[JUnit5] Assertions 기본 사용법
Jupiter
에서 제공하는 Assertions
에 대해서 알아보자.
자주 사용하는 Assertions
- assertEqulas(expected, actual)
- 실제 값이 기대한 값과 같은지 확인
- assertNotNull(actual)
actual
이null
이 아닌지
- assertTrue(boolean)
- 조건이 참(
true
)인지 확인
- 조건이 참(
- assertAll(executables…)
- 모든 확인 구문 확인
- assertThrows(expectedType, executable)
- 예외 발생 확인
- assertTimeout(duration, executable)
- 특정 시간 안에 로직이 완료되는지 확인
- 로직이 완료될 때 까지 기다림
- assertTimeoutPreemptively(expectedType, executable)
- 특정 시간 안에 로직이 완료되는지 확인
- 특정 시간 안에 로직이 완료 안되면 바로 테스트 종료
- 별도의 스레드에서 테스트를 수행
ThreadLocal
을 사용하는 로직인 경우 주의- 스프링에서
JPA
를 이용하여 쿼리를 수행할 때 롤백이 안될 수도 있음- 스프링 트랜잭션 처리는 기본적으로
ThreadLocal
전략
- 스프링 트랜잭션 처리는 기본적으로
실습
아래와 같은 클래스를 테스트한다고 가정해봅시다!
CalmDownMan
@Data
public class CalmDownMan {
private String name;
private int age;
private CalmDownManStatus status;
public CalmDownMan(int age) {
if(age < 0) {
throw new IllegalArgumentException("나이는 0보다 커야합니다.");
}
this.age = age;
this.status = CalmDownManStatus.OFF_AIR;
}
}
assertEqulas
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertEquals 테스트")
void assertEqualsTest() {
CalmDownMan calmDownMan = new CalmDownMan(40);
// 람다로 작성하면 지연연산을 하기 때문에
// 테스트가 실패 했을때만 문구를 표시한다.
// 성능에 도움이 된다.
assertEquals(calmDownMan.getAge(), 40, () -> "침착맨의 나이는 "+calmDownMan.getAge()+"살 입니다.");
assertEquals(calmDownMan.getStatus(), CalmDownManStatus.OFF_AIR, () -> "침착맨을 생성하면 기본 상태는 "+CalmDownManStatus.OFF_AIR+" 입니다.");
}
}
message
에 해당하는 부분을 람다로 작성하면,
람다는 지연 연산을 하기 때문에 테스트가 실패 했을 경우에만 String
연산을 수행하게 됩니다.
assertNotNull
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertNotNull 테스트")
void assertNotNullTest() {
CalmDownMan calmDownMan = new CalmDownMan(40);
assertNotNull(calmDownMan, () -> "침착맨을 생성하면 null이 아닙니다.");
}
}
assertTrue
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertTrue 테스트")
void assertTrueTest() {
CalmDownMan calmDownMan = new CalmDownMan(40);
assertTrue(calmDownMan.getAge() == 40, () -> "침착맨의 나이는 "+calmDownMan.getAge() +" 입니다.");
}
}
assertAll
assertAll
을 사용하면 모든 테스트 구문을 확인할 수 있습니다.
중간에 테스트가 실패해도 모든 테스트 구문이 실행 됩니다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertAll 테스트")
void assertAllTest() {
CalmDownMan calmDownMan = new CalmDownMan(40);
assertAll(
() -> assertEquals(calmDownMan.getAge(), 20, () -> "침착맨의 나이는 "+calmDownMan.getAge()+"살 입니다."),
() -> assertEquals(calmDownMan.getStatus(), CalmDownManStatus.OFF_AIR, () -> "침착맨을 생성하면 기본 상태는 "+CalmDownManStatus.OFF_AIR+" 입니다."),
() -> assertNotNull(calmDownMan, () -> "침착맨을 생성하면 null이 아닙니다."),
() -> assertTrue(calmDownMan.getAge() > 40, () -> "침착맨의 나이는 "+calmDownMan.getAge() +" 입니다.")
);
}
}
1번 테스트 실패해도
그다음 테스트를 실행하여 3번 테스트도 실패한 것을 알 수 있습니다.
assertThrows
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertThrows 테스트")
void assertThrowsTest() {
IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new CalmDownMan(-10));
String message = e.getMessage();
assertEquals("나이는 0보다 커야합니다.", message);
}
}
assertTimeout
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertTimeout 테스트")
void assertTimeoutTest() {
assertTimeout(Duration.ofMillis(100), () -> {
CalmDownMan calmDownMan = new CalmDownMan(10);
Thread.sleep(1000);
});
}
}
Duration
에서 설정한 100ms
를 초과하면 테스트에 실패합니다.
테스트를 이미 실패했지만, 해당 로직이 완료될 때까지 테스트를 수행합니다.
테스트를 수행하는데 1초 33ms
가 걸린것을 확인할 수 있습니다.
assertTimeoutPreemptively
assertTimeoutPreemptively
는 별도의 스레드에서 코드블록을 실행하기 때문에ThreadLocal
을 사용하는 로직을 수행할 시 주의해야 합니다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
class CalmDownManTest {
@Test
@DisplayName("assertTimeout 테스트")
void assertTimeoutPreemptivelyTest() {
/**
* 특정 시간안에 실행이 안되면 바로 테스트 종료
* 별도의 스레드에서 코드블록을 실행함
* ThreadLocal을 사용하는 로직은 주의해야 합니다.
*
* 예를 들어 스프링 트랜잭션 처리는 기본적으로 ThreadLocal 전략을 사용합니다.
* (ThreadLocal은 다른 스레드간 메모리 공유가 불가합니다.)
* assertTimeoutPreemptively()는 별도의 스레드에서 코드블록을 실행하기 때문에
* 스프링의 트랜잭션 설정을 가지고 있는 스레드(ThreadLocal을 사용)를 실행할 수 없습니다.
*
* 따라서 롤백이 안되고 DB에 그대로 반영될 수도 있습니다.^^
*/
assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
CalmDownMan calmDownMan = new CalmDownMan(40);
Thread.sleep(1000);
});
}
}
Duration
에서 설정한 100ms
를 초과하면 테스트에 실패합니다.
테스트를 실패하는 즉시 테스트를 종료 합니다.
테스트를 수행하는데 116ms
가 걸린것을 확인할 수 있습니다.
참고
728x90
반응형
'테스트 > 0+ JUnit' 카테고리의 다른 글
[JUnit] 회원가입 API 컨트롤러, 서비스, 리포지토리 테스트 예제 (5) | 2023.06.09 |
---|---|
[JUnit5] 인스턴스 테스트와 테스트 순서대로 실행하는 방법 (0) | 2023.05.17 |
[JUnit5] 테스트 인자 값 타입 변환하는 방법 (0) | 2023.05.17 |
[JUnit5] 환경변수 조건에 따라 테스트 실행하는 방법 (0) | 2023.05.05 |
[JUnit5] JUnit5 기본 어노테이션 (0) | 2023.05.04 |