김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 보면서 공부한 내용입니다.
: db에 접근해서 도메인 객체를 db에 저장하고 관리
-> 아직 db가 선정되지 않았으므로 메모리구현체 MemoryMemberRepository
사용
-> 실제 저장/조회 로직의 구현은 여기에
- 생성자가 딱 하나면 @Autowired 생략 가능
: 요즘은 널이 반환될때의 처리를 Optional로 감싸서함
: 동시성 문제가 고려되어 있지 않음, 실무에서는 ConcurrentHashMap, AtomicLong 사용 고려
: 자바용 유닛테스트 프레임워크
-> 구현한 기능에 대한 단위 테스트가 가능하다.
-> 클래스 레벨 단위로도 테스트가 가능하다.
@Test
를 붙혀준다import org.junit.jupiter.api.Test;
@Test
....
System.out.println("result = "+ (result == member));
매번 일일이 눈으로 검증할 수 없으므로 사용 x
org.junit.jupiter.api.Assertions
****
Assertions.assertEquals(result, member);
import static org.assertj.core.api.Assertions.*;
assertThat(member).isEqualTo(result);
가장 많이 사용하는 방법
@Test
public void save() {
Member member = new Member();
member.setName("spring");
repository.save(member);
Member result = repository.findById(member.getId()).get();
//System.out.println("result = "+ (result == member));
//Assertions.assertEquals(result, member);
//Assertions.assertThat(member).isEqualTo(result);
}
각 테스트마다의 실행 순서가 보장되지 않으므로 순서에 관계없이, 의존관계 없이 독립적으로 설계해야됨
→ 하나의 테스트가 끝날때마다 repository 깔끔하게 지워줘야됨
@AfterEach
public void afterEach() {
repository.clearStore();
}
와 같이 매 테스트케이스 실행 후 repository clear해줘야함
검증할 수 있는 테스트 틀을 먼저 만들고, 구현 클래스를 만들어서 돌려보기
-> 오늘 한 방법의 반대 순서
: 핵심 비즈니스 로직의 구현
-> 레포지토리보다 더 비즈니스 의존적으로 설계해야함
@Test
void 회원가입() {
//given -> 검증 데이터
//when -> 검증하려는 것
//then -> 검증하는 부분
}
와 같이 세부분으로 나눠서 테스트하면 쉬움
정상플로우 뿐만 아니라 예외 플로우에 대한 처리가 더 중요함
→ 이 예제에서 중복 회원 검증 로직 테스트
memberService.join(member1);
try {
memberService.join(member2); //두번째 조인시에 예외가 발생해야
fail(); //정상적으로 예외가 발생하지 않은 경우의 처리
} catch (IllegalStateException e) {
//예외가 정상적으로 발생한 경우
Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
Service와 ServiceTest에서 다른 두개의 repository를 사용한다.
MemberService.java
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
...
}
MemberServiceTest.java
class MemberServiceTest {
MemberService memberService = new MemberService();
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
...
}
MemberService와 MemberServieTest가 각자 다른 repository를 생성해서 사용할 때, 문제가 될 수 있음
→ 같은 인스턴스 사용 하도록 수정해줘야
MemberService.java
public class MemberService {
private final MemberRepository memberRepository;
//직접 new로 생성하는 것이 아닌 외부에서 넣어줄 수 있도록 -> dependency injection
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
MemberServiceTest.java
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
...
}
@BeforeEach
는 각 테스트 실행 전에 호출되어 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어줌
-> 테스트끼리의 독립성 보장
김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 보면서 공부한 내용입니다.
오..나도 오늘 들었는데 정리 잘해따..