해당 레포지토리는 테스트 코드 추가를 위한 토이 프로젝트 입니다. 코드가 얼마나 정상 동작하는지, 프로덕션에서 잘 동작하는지를 검증하지는 말아주세요. 스프링에 테스트를 넣는 과정을 보여드리기 위해 만들어진 레포지토리입니다. 당연히 완벽하지 않습니다.
h2를 이용하여 auto create table을 하고 있기 때문에 바로 실행이 가능합니다.
단 이 프로젝트는 사용자가 가입할 때 이메일 인증을 하기위해 메일을 발송하는 코드가 있습니다.
이메일이 제대로 발송되는지 확인해보고 싶으신 분들은 해당 document 파일을 따라해주세요. 관련된 자료는 라이브러리나 Gmail 정책에 따라 UI와 방법이 달라질 수 있습니다. 최신화 된 정보를 제공하지 않으니, 가급적 문서를 참조해주시고, contribution 해주시면 감사하겠습니다.
@ExtendWith(SpringExtension.class)
일반적으로 스프링부트 프로젝트를 만들면 나오는 @SpringBootTest 어노테이션은 전체 어플리케이션 컨텍스트를 로드하게 됨
그래서 테스트를 할 때마다 전체 어플리케이션 컨텍스트를 로드하게 되어 테스트가 느려지는 단점이 있음
필요한 부분만 테스트할 때는 해당 어노테이션을 사용하는 게 맞음
@DataJpaTest
스프링 데이터 JPA 관련된 설정만 로드함
근데, @ExtendWith 어노테이션을 사용하지 않아도 됨 (내장되어 있음)
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
MockMVC 설정하는 어노테이션
내장된 데이터베이스를 사용하는 어노테이션
- 모든 테스트가 h2를 필요로 함
- 문제점
- 중형 테스트가 되기 때문에, 테스트 부담이 큼
- ElasticSearch를 사용하는 경우, Embedded DB가 없기 때문에, 테스트가 불가능함 ➡️ 잘못된 테스트
- 문제점
- 원인 : 레이어드 아키텍처
- DB 위주의 설계를 하게 만듦
- 동시 작업을 하게 됨 (Repository - Service - Controller 순으로 만들어야 작업이 가능함.)
- 도메인(비즈니스 문제를 해결하는 객체 모델)이 죽음
- 도메인 레이어를 만들고, 기존의 서비스가 하던 역할을 도메인 레이어로 옮겨야 함
- 도메인과 영속성 객체를 구분하겠다 라는 의미
이런 식으로 전개하게 되면
서비스 레이어는 기존에 데이터베이스에 지나친 의존을 하고 있었다.
이를 도메인 레이어를 생성하고,
레포지토리 인터페이스를 만들고, 레포지토리에 대한 의존성 역전을 했다
컨트롤러는 지금까지 서비스를 의존하고 있었다.
서비스 인터페이스를 만들고, 서비스에 대한 의존성 역전을 했다.
--> 이제 모든 외부 모듈에 대해서 의존성 역전을 하겠음
외부 모듈: 데이터베이스, 메일 발송, 외부 API, 외부 서비스 등등
---> 그래서, Persistence Layer는 Infrastrucutre Layer로 변경하겠음
도메인 별로 레이어를 가진다.
예를 들어, posts 도메인을 users 도메인에 의존하게 되면, users 도메인을 테스트할 때, posts 도메인을 테스트해야 한다.
➡️ 소프트웨어공학에서는 해악이라고 보고 있음
모델 + Entity : JPA 엔티티
모델 : 비즈니스 모델
- 명령은 상태를 바꾸는 메소드
void 타입이어야 함 - 조회는 값을 반환하는 메소드
상태를 변환해서는 안 됨
반환 타입이 있어야 함
➡️ Repository 대신 Reader/Writer
- find: Optional을 반환한다는 의미로 많이 사용
- get: 애초에 데이터가 없으면 에러를 던진다는 의미가 내포되어 있음
Thread-safe로 구현되어 멀티스레드에서 syncronized 없이 사용할 수 있으며, 성능도 좋음 원자적 연산을 지원하게 됨
- 카운터
- 성능 최적화 : synchronized를 사용하지 않고, 성능을 최적화 할 수 있음
- 값이 동시에 변하는 것을 막음
서비스 레이어 테스트를 소형 테스트로 만들기 위해 사용됨 (ID 생성)
