실제 테스트에서 검증하고자 하는 내용을 확인하는 기능
org.junit.jupiter.api.Assertions.*
마지막 매개변수로 Supplier<String> 타입의 인스턴스를 람다 형태로 제공할 수 있다.
AssertJ, Hemcrest, Truth 등의 라이브러리를 사용할 수도 있다.
assertThatNotNull, assertEquals, assertTrue
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {
@Test
@DisplayName("스터디 만들기")
void create_new_Study() {
Study study = new Study(-10);
assertNotNull(study);
assertEquals(StudyStatus.DRAFT, study.getStatus(),
() -> "스터디를 처음 만들면" + StudyStatus.DRAFT+ "상태다.");
/*
assertEquals(StudyStatus.DRAFT, study.getStatus(),"스터디를 처음 만들면 상태값이 DRAFT여야 한다.");
위처럼 말고, Line 15처럼 람다식으로 만들어주는게 더 좋다.
람다식을 쓸 경우 실패했을 경우에만 문자열 연산 비용이 들지만, 두 번째는 실패하든 성공하든, 문자열 연산 비용이 든다.
문자열 계산 하는 비용이 들 것 같으면 람다식을 쓰는 게 성능상 이점을 가질 수 있다. 위와 같은 경우.
*/
assertTrue(study.getLimit() > 0, "스터디 최대 참석 인원은 0보다 커야 한다.");
}
assertAll()로 묶은 후,
@Test
@DisplayName("스터디 만들기")
void create_new_Study() {
Study study = new Study(-10);
assertAll(
() ->assertNotNull(study),
() ->assertEquals(StudyStatus.DRAFT, study.getStatus(),
() -> "스터디를 처음 만들면" + StudyStatus.DRAFT+ " 상태다."),
() ->assertTrue(study.getLimit() > 0, "스터디 최대 참석 인원은 0보다 커야 한다.")
);
// 3개의 assert문을 모두 실행하기 때문에, 3개중 2개가 깨져도 모두 실행할 수 있다.
}
예외 발생 확인
@Test
@DisplayName("스터디 만들기")
void create_new_Study() {
IllegalArgumentException exception =
assertThrows(IllegalArgumentException.class, () -> new Study(-10));
String message = exception.getMessage();
assertEquals("limit은 0보다 커야 한다.",message);
}
package com.example.testingweb.validatingforminput;
public class Study {
private StudyStatus status = StudyStatus.DRAFT;
private int limit;
public Study(int limit) {
if(limit < 0) {
throw new IllegalArgumentException("limit은 0보다 커야 한다.");
}
}
public int getLimit() {
return limit;
}
public StudyStatus getStatus() {
return this.status;
}
}
assertTimeout
@Test
@DisplayName("스터디 만들기")
void create_new_Study() {
assertTimeout(Duration.ofMillis(100), () -> {
new Study(10);
Thread.sleep(300);
});
}
----------------------------------------------------------------------------
/*
100이 넘으면 300까지 기다릴 필요 없이 바로 종료, assertTimeoutPreemptively
주의해서 사용하여함. 테스트코드에서 이 코드블럭은 별도의 쓰레드에서 실행하기 때문에
만약에 ThreadLocal을 사용하는 코드블럭이 있다면, 예상치 못한 에러가 발생할 수 있다.
스프링 트랜잭션 전략 같은 경우는 ThreadLocal을 기본적으로 사용을 하는데 ThreadLocal는 다른 Thread는 공유가 안되기 때문에 스프링이 만든 트랜잭션 설정이 적용이 제대로 안될 수 가 있다.
트랜잭션은 롤백을 기본적으로 실행을 하는데 롤백이 안되고 DB에 반영이 되는 경우가 생길 수 있다. 트랜잭션 설정을 가지고 있는 쓰레드와 별개로 실항하기 때문이다. 쓰레드와 관련이 없는 코드를 실행할 경우 괞찮다.
*/
@Test
@DisplayName("스터디 만들기")
void create_new_Study() {
assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
new Study(10);
Thread.sleep(300);
});
}