< 개발 순서 >
1. 서비스, 리포지토리 계층 개발
2. 테스트 케이스 작성해서 검증
3. 마지막 웹 계층 적용
@Service
@Transactional : 트랜잭션, 영속성 컨텍스트
readOnly=true : 데이터의 변경이 없는 읽기 전용 메서드에 사용, 영속성 컨텍스트를 플러시 하지 않으므로 약간의 성능 향상(읽기 전용에는 다 적용)
데이터베이스 드라이버가 지원하면 DB에서 성능 향상
@Autowired
생성자 Injection 많이 사용, 생성자가 하나면 생략 가능
join()
findMembers()
findOne()
** 스프링 필드 주입 대신 생성자 주입 사용
@RequiredArgsConstructor : final 있는 필드만 가지고, 생성자를 만들어준다.
📍 MemberRepository
@Repository
public class MemberRepository {
@PersistenceContext
EntityManager em;
...
}
/** 변경 */
@Repository
@RequiredArgsConstructor
public class MemberRepository {
private final EntityManager em;
...
}
ctrl + shift + T : 테스트 생성
[ 기능 설명 ]
📍 회원가입( )
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Autowired EntityManager em;
@Test
public void 회원가입() throws Exception {
//Given
Member member = new Member();
member.setName("kim");
//When
Long saveId = memberService.join(member);
//Then
em.flush();
assertEquals(member, memberRepository.findOne(saveId));
}
📍중복 회원 예외( )
//When
memberService.join(member1);
memberService.join(member2); //예외가 발생해야 한다.(똑같은 이름을 2번 넣었으니까)
try{
memberService.join(member2);
} catch (IllegalStateException e){
return;
}
@Test(expected = IllegalStateException.class)
public void 중복_회원_예외() throws Exception {
//Given
Member member1 = new Member();
member1.setName("kim1");
Member member2 = new Member();
member2.setName("kim2");
//When
memberService.join(member1);
memberService.join(member2);
//Then
fail("예외가 발생해야 한다.");
}
@Test(expected = IllegalStateException.class) : 예외처리 부분을 지울 수 있다.
[ 기술 설명 ]
@RunWith(SpringRunner.class) : 스프링과 테스트 통합
@SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
@Transactional : 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
테스트는 케이스 격리된 환경에서 실행하고, 끝나면 데이터를 초기화하는 것이 좋다.
=> 메모리 DB를 사용하는 것이 가장 이상적
테스트 케이스를 위한 스프링 환경과, 일반적으로 애플리케이션을 실행하는 환경 구분을 위해
설정 파일 다르게 사용
📍 test/resources/application.yml
해당 위치에 없을 경우 src/resources/application.yml 설정 파일을 읽는다.
스프링 부트는 datasource 설정이 없을 경우, 기본적으로 메모리 DB를 사용하고, driver-class도 현재 등록된 라이브러리를 보고 찾아준다.
추가로 ddl-auto, create-drop 모드로 동작하므로, JPA 관련된 별도 추가 설정 하지 않아도 된다.