CS log
[스프링 입문] 회원 관리 예제 - 회원 서비스 개발, 회원 서비스 테스트 본문
MemberService를 개발해보려고 한다. service는 비즈니스에 의존적으로(와 관련된 용어를 사용하여) 설계해야한다.
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
/*
회원가입
*/
public Long join(Member member){
// 같은 이름이 있는 중복 회원 안됨
Optional<Member> result = memberRepository.findByName(member.getName());
result.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
memberRepository.save(member);
return member.getId();
}
}
참고로 아래와 같이 쓸 수도 있다.
public Long join(Member member){
// 같은 이름이 있는 중복 회원 안됨
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
memberRepository.save(member);
return member.getId();
}
이때 cntrl + T를 해서 extract method 할 수 있다.
public Long join(Member member){
// 같은 이름이 있는 중복 회원 안됨
extracted(member);
memberRepository.save(member);
return member.getId();
}
private void extracted(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
이후 완성된 코드!
package hello.hello_spring.service;
import hello.hello_spring.domain.Member;
import hello.hello_spring.repository.MemberRepository;
import hello.hello_spring.repository.MemoryMemberRepository;
import java.util.List;
import java.util.Optional;
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
/*
회원가입
*/
public Long join(Member member){
// 같은 이름이 있는 중복 회원 안됨
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
/*
전체회원 조회
*/
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
}
이제 memberservice를 테스트해보겠다. memberservice에 ctrl + shift + t 를 하면 아래와 같이 팝업이 뜬다. 그리고 테스트 파일이 자동으로 만들어 진다. test 파일 안에
테스트는 과감하게 한글로 만들어도 된다. 왜냐하면 직관적으로 쉽게 알아들을 수 있고 실제 작동 코드라고 보지 않기 때문!
이때 추천하는 건 given, when, then 형식이다. 이거에 따라서 하면 좋다.
+) assertThat 이 잘 안되는 오류가 발생했다. 이 오류는 예전에 개발할 때도 많이 발생했었는데,
import static org.assertj.core.api.Assertions.assertThat;
이렇게 Import를 해주고 test 함수에서는 assertThat 으로 시작하는 함수를 작성해줘야 한다. import 문의 중요성 ,,,😅
그래서 then 의 로직을 설명해보자면, 생성된 멤버의 아이디를 받아서 그 멤버의 이름과, 저장된 member들의 이름 중 일치하는 이름이 있는지를 테스트하는 것이다. 이렇게 함으로써 회원가입이 잘 작동하는지 볼 수 있다.
그러나 저 코드는 매우 단순하기에 보충해야할 점이 있다. 바로 중복 확인!
아래가 MemberService.java 파일 코드의 한 부분인데, "이미 존재하는 회원입니다." 문구와 정확히 일치해야 한다.
public Long join(Member member){
// 같은 이름이 있는 중복 회원 안됨
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
그리고 다른 방법으로도 검증 성공했다. assertthrows는 memberservice에 member2를 넣었을 때 예외가 발생(중복 발생)하면 테스트를 통과한다는 뜻이다. 훨씬 더 가독성이 좋고 간결함을 알 수 있다.
아래 코드는 cmd+option+v 키로 변수 e를 받는 방식으로 조금 수정한 거다.
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));// memberservice를 실행했을 때 예외가 발생하면 테스트 통과
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
IllegalStateException : 객체가 현재 상태에서 수행할 수 없는 작업을 시도할 때 발생합니다. 즉, 메서드가 호출되기 위한 조건이 충족되지 않았을 때 던져지는 예외
NullPointerException : 객체가 null인 상태에서 그 객체의 메서드나 필드에 접근하려고 할 때 발생
테스트를 할 때마다 데이터가 clear 되는 코드를 추가해주었는데,
이때 memberservice에서 사용하는 memorymemberrepository와 test에서 생성하는 membermemoryrepository는
서로 다른 객체이다. 현재 Membermemoryrepository에서 회원 저장이 static이지만, 만약 static이 아니게 된다면 ... db 안 내용물이 달라져 문제가 발생할 수 있다. 같은 걸로 테스트하는게 맞는데, 다른 레포지토리로 테스트되는 것이다.
DI : Dependent Injection
즉 memberservice 입장에서 내가 회원 레포지토리를 생성하지 않고 누군가 생성한 걸 넣어주는 로직!
'Spring & Spring Boot' 카테고리의 다른 글
[스프링 입문] 스프링 빈과 의존관계 (1) | 2024.11.14 |
---|---|
Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks (0) | 2024.10.03 |
[스프링 입문] 회원 관리 예제 - 백엔드 개발 (2) | 2024.10.02 |
[스프링 입문] 스프링 웹 개발 기초 (6) | 2024.09.22 |
[스프링입문] 빌드하고 실행하기 (1) | 2024.09.08 |