ํ์ ์ํฐํฐ
@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member extends BaseTimeEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEMBER_ID")
private Long id;
@Column(nullable = false, unique = true)
private String email; // ์์ด๋
@Column(nullable = false)
private String loginPw; // ๋น๋ฐ๋ฒํธ
@Column(nullable = false)
private String verifiedPw; // ๋น๋ฐ๋ฒํธ ํ์ธ
@Column(nullable = false, unique = true)
private String name; // ์ด๋ฆ
private int age; // ๋์ด
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 30)
private RoleType role; // ๊ถํ
/* ํจ์ค์๋ ์ํธํ ๊ด๋ จ */
public void encodePassword(PasswordEncoder passwordEncoder){
this.loginPw = passwordEncoder.encode(loginPw);
}
/* ๊ถํ ๋ถ์ฌ */
public void addMemberAuthority() {
this.role = RoleType.USER;
}
}
public enum RoleType {
USER, ADMIN
}
Member ์ํฐํฐ๋ ์์ ๊ฐ์ต๋๋ค.
์ฌ์ฉ์๋ ํ์๊ฐ์ ์ ์งํํ๊ธฐ ์ํด ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ, ๋น๋ฐ๋ฒํธ ํ์ธ, ์ด๋ฆ, ๋์ด๋ฅผ ์ ๋ ฅํด์ผ ํฉ๋๋ค.
ํ์ ๋ฆฌํฌ์งํ ๋ฆฌ
public interface MemberRepository extends JpaRepository<Member, Long> {
boolean existsByEmail(String email);
boolean existsByName(String name);
Optional<Member> findByEmail(String email);
}
ํ์ ์๋น์ค
์ญํ ๊ณผ ์ฌ์ฉ์ ๋ถ๋ฆฌํ๊ธฐ ์ํด MemberService ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํ, MemberServiceImpl์ด ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค.
public interface MemberService {
boolean confirmEmail(String email);
boolean confirmName(String name);
void createMember(SignupRequestDTO signupRequestDTO);
Optional<Member> findByEmail(String email);
}
@Service
@RequiredArgsConstructor
@Transactional
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Override
public boolean confirmEmail(String email) {
return memberRepository.existsByEmail(email);
}
@Override
public boolean confirmName(String name) {
return memberRepository.existsByName(name);
}
@Override
public void createMember(SignupRequestDTO signupRequestDTO) {
Member member = signupRequestDTO.toEntity();
member.addMemberAuthority();
member.encodePassword(passwordEncoder);
if(findByEmail(signupRequestDTO.getEmail()).isPresent()) {
}
}
@Override
public Optional<Member> findByEmail(String email) {
return Optional.empty();
}
}
ํ์ ์ปจํธ๋กค๋ฌ
@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberController {
private final MemberServiceImpl memberServiceImpl;
@GetMapping("/confirmEmail/{email}")
public ApiResult<?> confirmEmail(@PathVariable("email") String email) {
if (memberServiceImpl.confirmEmail(email)) {
throw new MemberException(ErrorStatus.MEMBER_EMAIL_ALREADY_EXISTS);
}
return ApiResult.onSuccess();
}
@GetMapping("/confirmName/{name}")
public ApiResult<?> confirmName(@PathVariable("name") String name) {
if (memberServiceImpl.confirmName(name)) {
throw new MemberException(ErrorStatus.MEMBER_NAME_ALREADY_EXISTS);
}
return ApiResult.onSuccess();
}
@PostMapping("/signup")
public ApiResult<?> signup(@RequestBody SignupRequestDTO requestDTO) {
SignupResponseDTO responseDTO = memberServiceImpl.createMember(requestDTO);
return ApiResult.onSuccess(responseDTO);
}
}
ํ์ ์๋น์ค ํ ์คํธ
class MemberServiceImplTest {
@Mock
private MemberRepository memberRepository;
@Mock
private PasswordEncoder passwordEncoder;
@InjectMocks
private MemberServiceImpl memberServiceImpl;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
@DisplayName("์ด๋ฉ์ผ ์ค๋ณต ํ์ธ")
void confirmEmail() {
String email = "test@example.com";
when(memberRepository.existsByEmail(email)).thenReturn(true);
boolean result = memberServiceImpl.confirmEmail(email);
assertTrue(result);
verify(memberRepository, times(1)).existsByEmail(email);
}
@Test
@DisplayName("์ด๋ฆ(๋๋ค์) ์ค๋ณต ํ์ธ")
void confirmName() {
String name = "testname";
when(memberRepository.existsByName(name)).thenReturn(true);
boolean result = memberServiceImpl.confirmName(name);
assertTrue(result);
verify(memberRepository, times(1)).existsByName(name);
}
@Test
@DisplayName("ํ์๊ฐ์
")
void createMember() {
SignupRequestDTO signupRequestDTO = SignupRequestDTO.builder()
.email("test@example.com")
.loginPw("password123")
.verifiedPw("password123")
.name("testname")
.age(25)
.build();
when(passwordEncoder.encode(any(String.class))).thenReturn("encodedPassword");
SignupResponseDTO responseDTO = memberServiceImpl.createMember(signupRequestDTO);
assertEquals(signupRequestDTO.getEmail(), responseDTO.getEmail());
assertEquals("encodedPassword", responseDTO.getLoginPw());
assertEquals(signupRequestDTO.getName(), responseDTO.getName());
assertEquals(signupRequestDTO.getAge(), responseDTO.getAge());
verify(memberRepository, times(1)).save(any(Member.class));
}
@Test
void findByEmail() {
String email = "test@example.com";
Member member = Member.builder().email(email).build();
when(memberRepository.findByEmail(email)).thenReturn(Optional.of(member));
Optional<Member> result = memberServiceImpl.findByEmail(email);
assertTrue(result.isPresent());
assertEquals(email, result.get().getEmail());
verify(memberRepository, times(1)).findByEmail(email);
}
}
ํ์ ์ปจํธ๋กค๋ฌ ํ ์คํธ
class MemberControllerTest {
@Mock
private MemberServiceImpl memberServiceImpl;
@InjectMocks
private MemberController memberController;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(memberController)
.setControllerAdvice(new MemberHandler())
.build();
}
@Test
@DisplayName("์ด๋ฉ์ผ ์ค๋ณต ํ์ธ")
void confirmEmail() throws Exception {
String email = "test@example.com";
when(memberServiceImpl.confirmEmail(email)).thenReturn(true);
mockMvc.perform(get("/member/confirmEmail/{email}", email))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.code").value(ErrorStatus.MEMBER_EMAIL_ALREADY_EXISTS.getCode()))
.andExpect(jsonPath("$.message").value(ErrorStatus.MEMBER_EMAIL_ALREADY_EXISTS.getMessage()));
}
@Test
@DisplayName("์ด๋ฆ ์ค๋ณต ํ์ธ")
void confirmName() throws Exception {
String name = "testname";
when(memberServiceImpl.confirmName(name)).thenReturn(true);
mockMvc.perform(get("/member/confirmName/{name}", name))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.code").value(ErrorStatus.MEMBER_NAME_ALREADY_EXISTS.getCode()))
.andExpect(jsonPath("$.message").value(ErrorStatus.MEMBER_NAME_ALREADY_EXISTS.getMessage()));
}
@Test
@DisplayName("ํ์๊ฐ์
")
void signup() throws Exception {
SignupRequestDTO requestDTO = SignupRequestDTO.builder()
.email("test@example.com")
.loginPw("password123")
.verifiedPw("password123")
.name("testname")
.age(25)
.build();
SignupResponseDTO responseDTO = new SignupResponseDTO(requestDTO.toEntity());
when(memberServiceImpl.createMember(any(SignupRequestDTO.class))).thenReturn(responseDTO);
mockMvc.perform(post("/member/signup")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"email\":\"test@example.com\", \"loginPw\":\"password123\", \"verifiedPw\":\"password123\", \"name\":\"testname\", \"age\":25}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.result.email").value("test@example.com"))
.andExpect(jsonPath("$.result.name").value("testname"))
.andExpect(jsonPath("$.result.age").value(25));
}
}
๋ค์ ๊ธ์์๋ ๋ณธ๊ฒฉ์ ์ผ๋ก JWT ๊ธฐ๋ฐ ๋ก๊ทธ์ธ์ ๊ตฌํํ ์์ ์ ๋๋ค.
'Project > ๐ ์ค๋ ๋ญ ๋จน์ง?' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JWT๋ฅผ ์ด์ฉํ ๋ก๊ทธ์ธ ๊ตฌํ (1) - ํ๋ก์ ํธ ์์ฑ (0) | 2024.06.23 |
---|