# 스프링 통합 테스트
- 스프링 컨테이너와 DB까지 연결한 통합 테스트를 진행해보자.
- 순수한 자바 코드로 테스트할 수 없다(데이터베이스 커넥션 정보도 스프링 부트가 들고있는등의 이유로 인해).

---

## 추가 설명

- 통합 테스트를 위해서는 직접 객체를 생성하는 것이 아니라 스프링 컨테이너에서 의존성을 가져와서 진행해야 한다.
- 사실 테스트는 제일 끝단에 있는 것이기 때문에 테스트 코드를 작성할 때는 가장 편한 방법을 사용하면 된다.
- 기존 코드들은 생성자를 통해 의존성을 주입하는 것이 좋지만 테스트 코드는 필요한 의존성을 주입한 뒤 테스트를 진행하면 끝이기 때문에 테스트 코드를 작성할 때 필드 기반으로 `@Autowired`를 사용하는 것도 편한 방법이다.

---

## @SpringBootTest
- 스프링 컨테이너와 테스트를 함께 실행한다.
- 테스트를 실행하면 스프링 서버가 올라가고 테스트가 완료되면 서버가 내려간다.

---

## @Transactional
- 데이터베이스는 기본적으로 트랜잭션이라는 개념이 있다. DB의 데이터를 수정할 경우 커밋을 해야 DB에 반영이 된다(`오토커밋` 이라는 것도 있다).
- 테스트가 끝난 뒤(DB의 데이터 수정을 마친 뒤)에 롤백해버리면 DB의 변경사항들이 반영이 되지 않는다.
- `@Transactional`를 테스트 클래스에 선언하면 테스트를 실행할 때 트랜잭션을 먼저 실행하고 DB의 데이터를 변경한 다음에 테스트가 끝나면 해당 데이터 변경사항들을 롤백해준다. 즉, 독립적으로 다음 테스트를 반복해서 실행할 수 있게 된다(이후 추가적으로 처리해주는 코드 없이도!).
- 테스트 케이스에 이 애노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백한다. 이렇게 하면 DB에 데이터가 남지 않으므로 다음 테스트에 영향을 주지 않는다.
- `@Transactional` 어노테이션을 서비스와 같은 것들에 선언하면 롤백하지 않고 정상적으로 동작하며, 테스트 케이스에 선언했을 때만 항상 롤백하도록 동작한다.
- `@Commit` 같은 어노테이션도 있다.

---

## 단위 테스트
- 순수하게 자바 코드로 진행하며, 최소단위로 진행되는 테스트이다.
- 가급적이면 순수한 단위 테스트가 훨씬 좋은 테스트일 확률이 높다.
- 그러므로 단위별로 쪼개서 테스트를 잘 할 수 있도록 해야하고 스프링 컨테이너 없이 테스트할 수 있도록 훈련해야 한다.
- 만약 스프링 컨테이너까지 올려서 테스트를 해야하는 상황이 발생한다면 그 테스트는 설계가 잘못되었을 확률이 높다.
- 통합 테스트도 물론 필요하지만 단위 테스트를 잘 만드는 것이 훨씬 좋은 테스트이다.

---