테스트가 순서에 상관없이 독립적으로 실행되며 결정적으로 수행되야 함
같은 입력 값이면 언제나 어떤 순서라도 같은 결과를 반환해야 함
멱등하다는 의미도 포함하고 있음
테스트들이 서로 순서에 상관 없이 독립적으로 수행되어야 하기 때문에
마틴 파울러는 비결정적 테스트의 문제점에 대해 언급하며 그 원인으로 테스트 격리의 부족을 이야기했다고 함
테스트 격리가 필요 없음
서로 다른 테스트에서같은 객체를 사용하지 않도록 하거나
공통 fixture를 사용할 경우 @BeforeEach 를 사용해 초기화
@DataJpaTest
데이터 계층에 관련된 빈들만 가지고 slice 테스트
DB에 접근하기는 함
해당 어노테이션을 사용하면 InMemory에서 실행되며 자동으로 @Transactional 어노테이션이 적용됨
InMemory가 뭐지? ❓
@Transactional 이란? ❓
@Transactional
기본전략이 트랜잭션 rollback
실제로는 데이터베이스의 상태를 변화시키지 않고 격리된 상황에서 테스트
Mock 프레임워크
실제 DB 근처에는 접근도 하지 않음
테스트 격리를 신경쓰지 않고 테스트할 수 있음
Mock 프레임워크가 뭐지? ❓
💡hint: Mockito…
Mock 프레임워크
MockMvc : Rest API 클라이언트 도구
@SpringBootTest vs @WebMvcTest ❓
💡hint: @WebMvcTest는 @DataJpaTest와 마찬가지로 해당 계층에 관련된 빈들만 가지고 slice 테스트 가능
@Transactional
인수 테스트에서는 사용할 수 없는 방법
@SprintBootTest 에서는 port 를 지정해 서버를 띄움
이때 HTTP 클라이언트와 서버는 각각 다른 스레드에서 실행됨
따라서 호출되는 쪽은 다른 트랜잭션으로 커밋되기 때문에 해당 어노테이션이 무의미함
DELETE query
@BeforeEach에서 테스트에 필요한 데이터를 생성하고 @AfterEach에서 데이터 삭제 요청을 보내는 방법
테스트에 필요한 데이터가 적은 경우 용이할 수 있음
하지만 필요한 데이터의 양이 많거나, 연관관계가 복잡한 경우 굉장한 비효율이 발생할 수 있음
TRUNCATE query
매 테스트 이후 모든 테이블을 초기화하는 방법
DELETE vs TRUNCATE ❓
DELETE query에 비해 좋은 이유
JPA의 경우 DELETE 요청이 오면 바로 DELETE를 하는 것이 아니라 SELECT로 조회 후 DELETE를 함
삭제를 수행할 때 트랜잭션 로그 공간을 적게 사용
DELETE는 행마다 lock을거는데 비해 TRUNCATE은 lock을 거는 수가 상대적으로 적은 시간에 테이블 초기화
스프링부트에서 제공하는 어노테이션
클래스 테스트가 실행되기 전에 @Sql이 가리키는 경로에 있는 SQL 실행이 먼저 일어남
따라서 이 파일안에 모든 테이블에 대한 TRUNCATE SQL을 미리 작성
하지만 엔티티 또는 연관관계 테이블이 추가될 때마다 파일을 수정해줘야 하는 단점이 있음
JPA에서 쿼리를 직접 만들 수 있는 EntityManager를 빈으로 주입
모든 테이블 이름을 조사해서 각각의 인수테스트가 시작할 때 TRUNCATE 쿼리를 실행시키는 방식
@DirtiesContext
현재 테스트가 실행되려는 컨텍스트에 이미 빈이 올라가 있으면 Dirties를 확인하고 컨텍스트를 새로 로드하는 방법
하지만 매번 테스트 하기전에 컨텍스트를 다시 로드하게 되면 테스트하는데 시간이 오래걸림