Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1차] 김은서 백엔드 과제 제출합니다. #4

Open
7beunseo opened this issue Sep 17, 2024 · 0 comments
Open

[1차] 김은서 백엔드 과제 제출합니다. #4

7beunseo opened this issue Sep 17, 2024 · 0 comments
Assignees
Labels
1차 과제 1차 과제입니다.

Comments

@7beunseo
Copy link

1. TDD 에 대한 이해

  • TDD란?
    TDD의 핵심은 작은 단위의 테스트 케이스를 작성하고 이를 통과시키는 코드를 작성하는 것이다. TDD(Test-Driven Development)는 테스트 주도 개발이라 할 수 있으며, 소프트웨어 개발 방법론 중 하나로, 개발 과정에서 테스트를 우선 작성하고 이를 통과시키는 것에 초점을 둔 방법론이다. TDD는 개발자가 코드를 작성하기 전에 테스트를 작성하고, 그 테스트를 통과하기 위해 필요한 코드를 작성하는 사이클을 반복한다.

  • TDD는 언제 필요할까? 왜 필요한가?
    TDD는 코드의 안정성을 높이고, 오버 엔지니어링을 방지하며, 필요한 기능만 정확하게 구현할 수 있다.
    또한, 기능 단위로 빠른 피드백을 받을 수 있어, 문제를 조기에 발견하고 수정하는 데 유리하다. 작은 단위로 코드를 작성하고 테스트하는 과정을 반복하기 때문에 생산성이 높아지고, 리팩토링과 재설계가 필요할 때도 시간을 절약할 수 있다.
    기존의 테스트 케이스를 바탕으로 새로운 기능을 쉽게 추가할 수 있으며, 자동화된 테스트 덕분에 테스트 기간을 단축하고, 전체적인 개발 속도를 높이는 데 기여한다.

참고 사이트
https://tech1.tistory.com/89

2. 수강신청 서비스 구현

필수 구현 사항

  1. 회원 가입 및 로그인 기능 구현(1차 과제)
    • 학생 및 관리자 계정을 위한 회원 가입 및 로그인 기능
    • 로그인한 사용자만 수강신청 기능을 이용할 수 있도록 설정

김은서 1차 과제 제출 레포지토리

3. 나의 이해와 의견

1. 회원가입

  • 회원가입 후 데이터베이스에 잘 저장되었는지, 그리고 비밀번호가 암호화되어 저장되었는지를 확인하는 테스트 코드를 작성했습니다.
  • 회원가입 시 중복된 아이디를 입력할 경우 예외를 처리하도록 설정하였기 때문에 해당 에러가 정확하게 발생하는지 테스트 코드를 작성했습니다.
    @Test
    void 유저_회원입() {
        // given
        SignUpDTO req = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);

        // when
        SignUpDTO.Res res = userService.signUp(req);

        // then
        Optional<UserEntity> findUser = userRepository.findById(res.getId());
        assertTrue(findUser.isPresent());

        UserEntity user = findUser.get();
        assertEquals(user.getUsername(), "eunseo");
        assertTrue(bCryptPasswordEncoder.matches("1234", user.getPassword()));
        assertEquals(user.getRole(), Role.ROLE_USER);
    }

    @Test
    void 중복_아이디_에러() {
        // given
        SignUpDTO req1 = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);
        SignUpDTO req2 = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);

        // when
        userService.signUp(req1);

        // then
        assertThrows(DuplicateUsernameException.class, () -> userService.signUp(req2));
    }

2. 로그인

  1. 로그인의 경우, 입력한 정보(username)가 데이터베이스에 있는지 확인 후 -> 해당 유저 정보로 토큰을 생성하는데, 이때 데이터베이스에 해당 유저가 있는지 확인하는 로직이 잘 동작하는지 확인하기 위한 테스트 코드를 작성하였습니다.
    @Test
    void 아이디로_유저_조회_성공() {
        // given
        SignUpDTO req = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);

        // when
        SignUpDTO.Res res = userService.signUp(req);

        // then
        UserDetails findUser = customUserDetailsService.loadUserByUsername("eunseo");
        assertNotNull(findUser);
    }

    @Test
    void 아이디로_유저_조회_실패() {
        // given
        SignUpDTO req = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);

        // when
        SignUpDTO.Res res = userService.signUp(req);

        // then
        assertThrows(UsernameNotFoundException.class, () -> customUserDetailsService.loadUserByUsername("eunseo12"));
    }

3. 토큰 유효성 검사

  • 로그인에 성공하면 JWT를 사용하여 토큰을 생성하는데, 토큰의 유효성 검사가 잘 동작하는지 확인하기 위한 테스트코드를 작성하였습니다.
  • 이때, 토큰의 시간이 만료되었는지도 검사합니다.
    @Test
    void 유효한_토큰_검사() {
        // given
        SignUpDTO req = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);
        SignUpDTO.Res res = userService.signUp(req);
        String jwt = jwtUtil.createJwt("accessToken", res.getUsername(), res.getRole().toString(), 1000000L);

        // when
        String username = jwtUtil.getUsername(jwt);

        // then
        assertTrue(userRepository.findByUsername(username).isPresent());
    }

    @Test
    void 유효하지_않은_토큰_검사() {
        // given
        String invalidToken = "invalid-jwt-token";

        // when & then
        assertThrows(MalformedJwtException.class, () -> jwtUtil.getUsername(invalidToken));
    }

    @Test
    void 만료된_토큰_검사() {
        // given
        SignUpDTO req = new SignUpDTO("eunseo", "1234", Role.ROLE_USER);
        SignUpDTO.Res res = userService.signUp(req);
        String expiredToken = jwtUtil.createJwt("accessToken", res.getUsername(), res.getRole().toString(), 1L);

        // when - 2초 대기
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // then
        assertThrows(ExpiredJwtException.class, () -> jwtUtil.getUsername(expiredToken));
    }

테스트코드 작성이 처음이라, Entity 작성 -> Repository 작성 -> Service 작성 -> Test 수행 -> Controller 작성 의 순서로 개발을 진행했는데, 이 방법이 맞는지 잘 모르겠습니다.

@7beunseo 7beunseo self-assigned this Sep 17, 2024
@7beunseo 7beunseo added the 1차 과제 1차 과제입니다. label Sep 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1차 과제 1차 과제입니다.
Projects
None yet
Development

No branches or pull requests

1 participant