🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

블로그

sein

[워밍업 클럽 4기 - 백엔드] Day 16 미션

미션MVC 기반에서 가장 많이 사용되는 3티어 레이어별로 특징과 테스트 방법을 정리해보자! Layered Architecture 일반적으로 controller(presentation) -> service(business) -> repository(persistence) 구조로 이루어져있다.레이어를 단계적으로 구분하는 이유는 관심사 분리가 목적이다. persistence LayerDB와 직접적인 소통을 하는 계층이며 CRUD 쿼리 작업을 처리한다.Business 계층에서 넘어온 데이터를 처리한다.주로 JPA와 QueryDSL을 사용한다.  테스트 방법클래스 레벨에서 @SpringBootTest, @DataJpaTest 어노테이션을 사용할 수 있다.@SpringBootTest를 사용하는 것을 더 추천한다(다른 테스트와의 환경 통합을 위해)작성한 쿼리가 의도대로 동작하는지 테스트한다. business Layer비즈니스 로직이 메인이다.presentation에서 데이터를 받으며 중요 비스니스 로직을 수행하고 persistence 계층으로 전달하는 중간다리 역할을 한다.  테스트 방법클래스 레벨에 @SpringBootTest를 사용하거나 Mock을 사용하는 경우 @ExtendWith(MockitoExtension.class)를 사용한다. 이 역시 환경의 통합을 위해 되도록이면 SpringBootTest를 사용하는 것이 좋다. 스트 객체를 생성할 때 관련 테스트 메서드에는 꼭 필요한 데이터만 파라미터로 넘겨받아 빌더 패턴을 활용한다.단위 테스트를 작성할 수도, persistence 계층와 통합해서 테스트할 수도 있다. presentation Layer외부 세계를 제일 처음 맞이하는 계층이다. 또한 외부 세계에 응답 데이터를 전달해주는 계층이다.  테스트 방법사용자 요청의 데이터에 최소한의 검증을 해야한다. (validation) 다만, 타입의 유효성 자체에 대한 검증이 아닌 도메인과 관련된 검증들은 presentation 계층이 아닌 더 내부에서 진행한다.클래스 레벨에 @WebMvcTest(className.class)를 사용한다.mock을 사용한다.직렬화, 역직렬화를 위해 ObjectMapper 객체가 필요하다.   출처인프런_워밍업_클럽_4기_BEPractical Testing: 실용적인 테스트 가이드

백엔드워밍업클럽박우빈테스트코드MVC

윤대

[인프런 워밍업 0기] JPA findById() vs getReferenceById()

다음은 JPA에서 연관관계 매핑이 되어있는 객체를 save하는 상황이다. @Transactional public void recordArrivalTime(Long memberId, LocalDate attendanceDate, LocalTime startTime) { Member member = memberRepository.findById(memberId); workTimeRecordService.recordArrivalTime(member, attendanceDate, startTime); }WorkTimeRecord를 save하기 위해서는 Member를 알아야만 했고,Member를 찾기 위해서 기존에는 Id값으로 Member를 찾아왔지만, 문득 이는 굉장히 '비효율적'이라는 생각이 들었다.WorkTimeRecord를 저장하기 위해 필요한 것은 Member의 Id 값이지, Member의 모든 정보를 찾아올 필요는 없었기 때문에 불필요한 select문이 발생하는 셈이다.그래서, 이리저리 알아보던 차, Proxy객체라는 존재와 getReferenceById()라는 JpaRepository의 메소드를 알게 되었다.Proxy는 여러 곳에서 쓰이는 용어이지만, JPA를 구현하고 있는 hibernate에서는 Proxy객체는 실제 Entity(여기서는 Member)를 상속 받은 껍데기 객체이다.Entity를 상속받았기 때문에 Entity의 모든 역할을 대신 수행할 수 있으나, 내부의 값은 모두 비어있는 상태가 된다.만일, 상태가 필요한 순간이 되면 그때 JPA의 영속성 컨텍스트를 통하여 실제 Entity를 조회하여 값을 찾아오게 된다.위와 같은 기술을 Lazy라고 한다.즉, 나의 처음의 고민은 이를 통해 해결할 수 있게 되었다. @Transactional public void recordArrivalTime(Long memberId, LocalDate attendanceDate, LocalTime startTime) { Member member = memberRepository.getReferneceById(memberId); workTimeRecordService.recordArrivalTime(member, attendanceDate, startTime); }이렇게, Proxy객체로 Member를 찾게 되면, 실제로 select문은 발생하지 않고 정상적으로 WorkTimeRecord에 Member값을 할당할 수 있게 된다. 

백엔드JPA인프런워밍업MVC

채널톡 아이콘