728x90
반응형
|
|
회원가입 & 로그인 요구사항 분석
- 아이디와 비밀번호, 이름, 닉네임(별명), 나이를 입력받습니다.
- 아이디는 중복될 수 없습니다.
- 비밀번호와 이름, 닉네임과 나이는 변경할 수 있습니다.
- 비밀번호는 암호화되어 데이터베이스에 저장됩니다.
- 회원을 포함한 모든 엔티티는 데이터베이스에 저장될 때, 등록 시간과 업데이트 시간을 등록하도록 하겠습니다.
- 로그인에 성공하면 JWT를 발급해주며, 이를 통해 사용자는 우리의 게시판 서비스 API를 이용할 수 있습니다.
- 회원가입으로는 USER 권한의 회원만 가입할 수 있습니다. ADMIN 권한은 직접 데이터베이스에 입력하여 지정해주도록 하겠습니다.
회원 엔티티 작성

@Table(name = "MEMBER")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@AllArgsConstructor
@Builder
public class Member extends BaseTimeEntity {
// pk
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id")
private Long id;
// 아이디
@Column(nullable = false, length = 30, unique = true)
private String username;
// 비밀번호
private String password;
// 실명
@Column(nullable = false, length = 30)
private String name;
// 별명
@Column(nullable = false, length = 30)
private String nickName;
// 나이
@Column(nullable = false)
private Integer age;
// 권한 -> USER, ADMIN
@Enumerated(EnumType.STRING)
private Role role;
public void updatePassword(PasswordEncoder passwordEncoder, String password){
this.password = passwordEncoder.encode(password);
}
public void updateName(String name){
this.name = name;
}
public void updateNickName(String nickName){
this.nickName = nickName;
}
public void updateAge(int age){
this.age = age;
}
public void encodePassword(PasswordEncoder passwordEncoder){
this.password = passwordEncoder.encode(password);
}
}
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public abstract class BaseTimeEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
@Column(updatable = true)
private LocalDateTime lastModifiedDate;
}
public enum Role {
USER, ADMIN
}
EnableJpaAuditing을 추가해줍니다.
엔티티 객체가 생성이 되거나 변경이 되었을 때 @EnableJpaAuditing 어노테이션을 활용해서 자동으로 값을 등록할 수 있다.
@EnableJpaAuditing
@SpringBootApplication
public class BoardApplication {
public static void main(String[] args) {
SpringApplication.run(BoardApplication.class, args);
}
}
위를 통해 다음 요구사항을 만족시켰습니다.
아이디와 비밀번호, 이름, 닉네임(별명), 나이를 입력받습니다.아이디는 중복될 수 없습니다.비밀번호와 이름, 닉네임과 나이는 변경할 수 있습니다.비밀번호는 암호화되어 데이터베이스에 저장됩니다.회원을 포함한 모든 엔티티는 데이터베이스에 저장될 때, 등록 시간과 업데이트 시간을 등록하도록 하겠습니다.- 로그인에 성공하면 JWT를 발급해주며, 이를 통해 사용자는 우리의 게시판 서비스 API를 이용할 수 있습니다.
- 회원가입으로는 USER 권한의 회원만 가입할 수 있습니다. ADMIN 권한은 직접 데이터베이스에 입력하여 지정해주도록 하겠습니다.
MemberRepository 생성

public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByUsername(String userName);
boolean existsByUsername(String userName);
}
Spring Data Jpa로 만들었습니다.
반응형
테스트 코드 작성
테스트 해야할 것들은 다음과 같습니다.
- 회원 저장
- 회원 저장시 아이디가 없으면 오류
- 회원 저장시 이름이 없으면 오류
- 회원 저장시 닉네임이 없으면 오류
- 회원 저장시 나이가 없으면 오류
- 회원 저장시 중복된 아이디가 있으면 오류
- 회원 수정
- 회원 삭제
- existsByUsername이 잘 작동하는지
- username으로 회원 찾기 기능이 잘 작동하는지
- 가입 시 생성시간이 잘 등록되었는지
@SpringBootTest
@Transactional
public class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@PersistenceContext EntityManager em;
private void clear(){
em.flush();
em.clear();
}
@AfterEach
private void afterEach(){
em.clear();
}
// 회원 저장
@Test
void 회원저장_성공() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
// when
Member saveMember = memberRepository.save(member);
// then
Member findMember = memberRepository.findById(saveMember.getId()).orElseThrow(() -> new RuntimeException("저장된 회원이 없습니다"));
Assertions.assertThat(findMember).isSameAs(member);
Assertions.assertThat(findMember).isSameAs(saveMember);
}
// 회원 저장시 아이디가 없으면 오류
@Test
void 회원저장_실패_회원가입시_아이디가_없음() throws Exception {
// given
Member member = Member.builder()
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
// when
// then
org.junit.jupiter.api.Assertions.assertThrows(Exception.class, () -> memberRepository.save(member));
}
// 회원 저장시 이름이 없으면 오류
@Test
void 회원저장_실패_회원가입시_이름이_없음() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
// when
// then
org.junit.jupiter.api.Assertions.assertThrows(Exception.class, () -> memberRepository.save(member));
}
// 회원 저장시 닉네임이 없으면 오류
@Test
void 회원저장_실패_회원가입시_닉네임이_없음() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.role(Role.USER)
.age(22).build();
// when
// then
org.junit.jupiter.api.Assertions.assertThrows(Exception.class, () -> memberRepository.save(member));
}
// 회원 저장시 나이가 없으면 오류
@Test
void 회원저장_실패_회원가입시_나이가_없음() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER).build();
// when
// then
org.junit.jupiter.api.Assertions.assertThrows(Exception.class, () -> memberRepository.save(member));
}
// 회원 저장시 중복된 아이디가 있으면 오류
@Test
void 회원저장_실패_회원가입시_아이디가_중복() throws Exception {
// given
Member member1 = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
Member member2 = Member.builder()
.username("username")
.password("1234567890")
.name("Member2")
.nickName("NickName2")
.role(Role.USER)
.age(22).build();
// when
memberRepository.save(member1);
clear();
// then
org.junit.jupiter.api.Assertions.assertThrows(Exception.class, () -> memberRepository.save(member2));
}
// 회원 수정
@Test
void 회원수정_성공() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member")
.nickName("NickName")
.role(Role.USER)
.age(22).build();
Member saveMember = memberRepository.save(member);
clear();
String updatePassword = "0987654321";
String updateName = "updateName";
String updateNickName = "updateNickName";
int updateAge = 20;
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// when
Member findMember = memberRepository.findById(member.getId()).orElseThrow(() -> new Exception());
findMember.updatePassword(passwordEncoder, updatePassword);
findMember.updateName(updateName);
findMember.updateNickName(updateNickName);
findMember.updateAge(updateAge);
em.flush();
// then
Member findUpdateMember = memberRepository.findById(member.getId()).orElseThrow(() -> new Exception());
Assertions.assertThat(findUpdateMember).isSameAs(findMember);
Assertions.assertThat(passwordEncoder.matches(updatePassword, findUpdateMember.getPassword())).isTrue();
Assertions.assertThat(findUpdateMember.getName()).isSameAs(updateName);
Assertions.assertThat(findUpdateMember.getNickName()).isSameAs(updateNickName);
Assertions.assertThat(findUpdateMember.getAge()).isSameAs(updateAge);
}
// 회원 삭제
@Test
void 회원삭제_성공() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
Member saveMember = memberRepository.save(member);
clear();
// when
memberRepository.delete(member);
clear();
// then
org.junit.jupiter.api.Assertions.assertThrows(
Exception.class,
() -> memberRepository.findById(member.getId()).orElseThrow(() -> new Exception())
);
}
// existsByUsername이 잘 작동하는지
@Test
void existsByUsername_작동테스트() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
// when
Member saveMember = memberRepository.save(member);
clear();
// then
Assertions.assertThat(memberRepository.existsByUsername(member.getUsername())).isTrue();
Assertions.assertThat(memberRepository.existsByUsername("username1")).isFalse();
}
// username으로 회원 찾기 기능이 잘 작동하는지
@Test
void findByUsername_작동테스트() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
// when
Member saveMember = memberRepository.save(member);
clear();
// then
Member findMember = memberRepository.findByUsername(member.getUsername()).orElseThrow(() -> new Exception());
Assertions.assertThat(memberRepository.findByUsername(member.getUsername()).get().getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(memberRepository.findByUsername(member.getUsername()).get().getName()).isEqualTo(member.getName());
Assertions.assertThat(memberRepository.findByUsername(member.getUsername()).get().getId()).isEqualTo(member.getId());
org.junit.jupiter.api.Assertions.assertThrows(Exception.class,
() -> memberRepository.findByUsername(member.getUsername()+"123")
.orElseThrow(() -> new Exception()));
}
// 가입 시 생성시간이 잘 등록되었는지
@Test
void 생성시간_테스트() throws Exception {
// given
Member member = Member.builder()
.username("username")
.password("1234567890")
.name("Member1")
.nickName("NickName1")
.role(Role.USER)
.age(22).build();
memberRepository.save(member);
// when
Member findMember = memberRepository.findByUsername(member.getUsername()).orElseThrow(() -> new Exception());
// then
Assertions.assertThat(findMember.getCreatedDate()).isNotNull();
Assertions.assertThat(findMember.getLastModifiedDate()).isNotNull();
}
}
전체 소스코드는 깃허브에서 확인하실수 있습니다.
https://github.com/IkJuLim/board
GitHub - IkJuLim/board
Contribute to IkJuLim/board development by creating an account on GitHub.
github.com
728x90
반응형
'프로젝트 > 게시판 프로젝트' 카테고리의 다른 글
| [SpringBoot/게시판] 게시판 API(2) - 프로젝트 생성 (0) | 2024.02.15 |
|---|---|
| [SpringBoot/게시판] 게시판 API(1) - 프로젝트 개요 (0) | 2024.02.15 |