본문 바로가기
Blog/Sparta

50% 달려온 항해 플러스 5기 백엔드 중간 후기 (feat. 테스트 코드도 못 짰던 내가 맞나? 가슴이 웅장해진다.)

by 코젼 2024. 7. 20.
728x90
반응형

 

 

수료 후기는 여기!

https://cojyeon.tistory.com/323

 

하얗게 불태웠다... 항해 플러스 5기 백엔드 수료 솔직 후기! (할인코드 있음 😎)

안녕하세요~~~~~!!!!!!!!드디어!!! 10주 간의 여정을 끝마치고 후기로 돌아온 코딩하는 젼이입니다 😜재밌게 봐주시고, 마지막에 할인 코드도 있으니까 할인 혜택도 받아가세요! 사담이 많아서 필

cojyeon.tistory.com

 

 

 

안녕하세요 코딩하는 젼이입니다 😎

항해 플러스 5기를 달려온지 벌써 5주차가 지나고 이번주 부터 6주차가 시작되었습니다.

6주차를 시작하기 전에 챕터 회고를 하고자 합니다.

 

그 전에 저를 잠깐 소개하자면, 저는 1년 동안 중견 기업에서 이커머스 PHP 개발자로 일했었고

회사 재정 상황이 안 좋아져서 현재는 퇴사하고 이직 준비 중입니다.

 

그리고 제일 중요한 부분, 저는 사실 항해 플러스 4기를 신청했던 사람이었습니다.

그런데 왜 5기가 되었냐? 

- 1주차에 스켈레톤 코드를 주셨는데 코드 하나도 안 읽힘

- 테스트 코드 하나도 못 짬

- 나는 지금 뭐하는 거지?

 

현재 저의 상태로는 시간 안에 과제를 구현할 수 없었고
무엇보다 기초 지식이 부족한 이 상태로는 좋은 커리큘럼에도 불구하고 많은 걸 얻어갈 수 없다고 판단했습니다.
그래서 고민 끝에 2주차에 기수 이전을 선택하게 되었고, 5기에 합류하기로 결정합니다.

 

5기까지 약 2개월 반의 시간이 있었고 저는 그 때동안 Spring + Java 에 대해서 깊게 공부하기로 결심합니다.

(일단 코드는 읽혀야 될 거 아니여?)

덤벼라 세상아

 

돌이켜보면 5기 합류 전까지 정말 열심히 준비했다고 생각합니다.

일단 제가 제일 걱정했던 부분인 테스트 코드와 코드 읽기 부분은 모두 해결이 됐거든요! 😎

 

그래서 지금 현재 커리큘럼 진행률 50% 인 상황에서 1개 빼고 All Pass 를 받을 수 있었습니다.

회고 적는 김에 나 자신 대단하다고 한 번 칭찬을 주고 싶네요 (참 잘했어요! 👏)

Fail 은 실수로 요구사항을 하나 누락해서.. 힝 요구사항을 잘 읽읍시다.

 

사실은 블랙 배지를 받기 위한 여정

배지 제도가 있어서 더 열심히 한 것도 있습니다.

블.랙.배.지 넌 내꺼야


서사는 이정도로 남겨 두고, 이제 정규 일정을 보겠습니다.

항해 플러스 백엔드 10주차 과정

 

제가 항해에 합류하면서 현재까지 진행한 부분은 이렇습니다.

- 사전 준비 과정

- 1~5주차

 

1~2주차에 TDD + 클린 아키텍처로 간단한 API 를 구현합니다.
저는 4기 과정에서도 말씀드렸듯이 테스트 코드를 1도 작성 못하는 사람이었고

4기 때는 막차를 타서 사전 준비 과정을 진행하지 못했었습니다.

이런 점이 아쉬워서 저는 이번에 사전 준비 과정을 진행했는데 정말 GOOD!!! 이었습니다.

 

이야기가 나온 김에 슬쩍 자랑 해보자면 저 포함해서 5명이서 TDD 스터디를 진행했었습니다.

결과적으로 팀원 분들이 너무 좋았고, 산출물도 꽤 맘에 들게 나왔습니다.

 

사전 스터디에 관련해서 궁금하시다면 Github 링크 확인 부탁드립니다.

도움이 되셨다면 Star⭐️ 한 번도 눌러주시면 감사하겠습니다 ㅎㅎ

https://github.com/kdelay/TDD-Study

 

GitHub - kdelay/TDD-Study: 📗 Test-Driven Development Study

📗 Test-Driven Development Study. Contribute to kdelay/TDD-Study development by creating an account on GitHub.

github.com

 

결론은 현재 자신이 테스트 코드 작성에 미흡하다는 생각이 드시고 시간이 여유가 되신다면

사전 준비 과정의 "방법론 스터디" 를 꼭!!!!!!! 신청하고 학습하시는 걸 추천드립니다 👍🏻

 

 

2주간의 TDD, 클린 아키텍처 과정을 끝내고 대망의 항해 플러스의 꽃 🌸

서버 구축이 시작되었다.

 

 

정말..........

힘들었지만 그만큼 얻어가는 게 많아서 좋은 챕터였습니다.

많은 분들과 소통하고 리뷰하면서 견문을 넓힐 수 있는 좋은 계기도 되었습니다.

(그리고 4주차 끝나고 네트워킹 파티했는데 치킨 진짜 개꿀맛이었습니다. 힘듬과 행복을 동시에? 단짠단짠 대박)

 

일단 저의 목표는 항상 주차별 A.L.L P.A.S.S 였기 때문에 구현과 테스트를 정말 열심히 했습니다.

인생을 살면서 이렇게까지 열정적이고 밤샘 과제하고 고민을 많이 했던 시기였다고 생각합니다.

처음으로 일주일 간 100시간을 넘겨서 과제를 진행했던 4주차

 

결과는? 서버 구축 진행한 챕터 3주 모두 Pass 를 받았습니다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

진짜 힘들었는데 팀원 분들이랑 (+다른 팀원 분들도) 모각코하고 서로 질의응답하는 시간 덕분에 버틸 수 있었던 것 같습니다.

 

저희 10조 팀 복 맞췄어요 화기애애한 우리 10조
다른 팀원분들도 항상 감사합니다 최고

 

50% 를 달려온 지금 모습을 회고하자면

- 전반적으로 레이어드 아키텍처의 구조를 잡을 수 있고 계층 간의 관계도를 이해할 수 있다.

- 단위 테스트와 통합 테스트를 분리해서 작성할 수 있다.

- Filter 와 Interceptor 의 차이점을 설명할 수 있다.

- Filter 에서 request, response 로깅을 진행할 수 있다.

- Interceptor 에서 토큰 검증을 진행할 수 있다.

- Scheduler 를 통해 토큰 상태 값을 변경할 수 있고 설정한 시간을 통해 예약 상태를 변경할 수 있다.

- 동시성 테스트의 중요성을 알고, 동시성 테스트를 처음 진행해보았다!!! (제일 기쁘다!!)

 

내 코드를 리뷰하고, 다른 사람의 코드를 리뷰하면서 내가 부족했던 점을 보완해 나가고 새로운 지식을 얻어갈 때 가장 즐거웠습니다. 😁


 

회고를 작성하면서 가장 중요한 부분!!!!!!

서버 구축 챕터를 진행하면서 삽질했던 경험을 살짝 정리해보겠습니다.

저 같은 실수는 안 하시길...

1. 좌석 예약할 때 좌석 번호가 0으로 초기화되는 문제
저는 Entity, Domain 을 분리하고 Entity 는 Infrastructure 레이어에서, Domain 은 Domain 레이어에서 관리하고 있었는데요
Infrastructure 에서 JPA 의 데이터를 받아서 Repository Impl 을 통해 Domain 으로 넘겨주는 작업을 하고 있었습니다.

그 과정에서 JPA에 Entity 를 파라미터로 넘겨줘야해서 Domain 으로 변경해주는 Mapper 클래스가 있는데,
변환을 하면서 seatNumber 의 값을 넘겨주지 않아서 0으로 초기화되는 문제였습니다.
    public static ConcertSeatEntity seatToEntity(ConcertSeat concertSeat) {
        return ConcertSeatEntity.builder()
                .id(concertSeat.getId())
                .concertEntity(ConcertMapper.toEntity(concertSeat.getConcert()))
                .concertScheduleEntity(ConcertMapper.scheduleToEntity(concertSeat.getConcertSchedule()))
                .userId(concertSeat.getUserId())
                .seatNumber(concertSeat.getSeatNumber()) // 이 부분 누락 됐었음
                .seatPrice(concertSeat.getSeatPrice())
                .seatStatus(concertSeat.getSeatStatus())
                .modifiedAt(concertSeat.getModifiedAt())
                .expiredAt(concertSeat.getModifiedAt())
                .build();
    }

Mapper 에서 항상 값이 잘 전달되고 있는지 확인합시다..
2. controller 에서 request 객체 데이터를 전달했음에도 불구하고 db 에서 데이터를 못 가져오는 문제
postman 으로 API 테스트를 진행하고 있었는데 계속 에러가 표시되는 겁니다.
꽤나 머리를 싸매고 있었는데 에러가 발생한 원인은 정말 황당했습니다.

concertScheduleId 를 넘겨줘야하는데 비슷한 concertSeatId 를 넘기고 있었습니다...
오타 항상 주의하세요.
3. Filter, Interceptor 를 적용하면서 인터셉터를 적용한 API 통합 테스트 난관
테스트가 잘 진행되지 않아서 굉장히 뇌가 아팠습니다.
@Import(WebMvcConfig.class) 를 통해 인터셉터를 설정해둔 파일을 불러와서 통합 테스트를 진행할 수 있었습니다.
필터와 인터셉터를 구현할 때는 항상 설정 파일을 확인할 것…
설정은 항상 중요합니다 ^^;

코드는 간단하게 일부 긁어왔습니다.
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {

    private final TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/waiting/token", "/concert/**", "/payment/**");
    }
}​

@WebMvcTest(controllers = WaitingTokenController.class)
@Import(WebMvcConfig.class)
@AutoConfigureMockMvc
class WaitingTokenControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Autowired
    ObjectMapper objectMapper;

    @MockBean
    WaitingTokenFacade waitingTokenFacade;

    @Test
    @DisplayName("POST /waiting/token 발급 및 조회 API 테스트")
    void testIssueTokenOrSearchWaiting() throws Exception {

        long userId = 1L;
        long concertId = 1L;

        String token = UUID.randomUUID().toString();
        WaitingTokenRequest request = new WaitingTokenRequest(userId, concertId);

        User user = new User(userId, BigDecimal.ZERO);
        WaitingToken waitingToken = new WaitingToken(1L, user, token, DEACTIVATE, LocalDateTime.now(), null);
        given(waitingTokenFacade.issueTokenOrSearchWaiting(userId, concertId)).willReturn(waitingToken);
        given(waitingTokenFacade.getRank(waitingToken.getId())).willReturn(0L);

        String req = objectMapper.writeValueAsString(request);

        //when & then
        mockMvc.perform(post("/waiting/token")
                        .header("Authorization", token)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(req)
                        .header("Authorization", "Bearer valid-token"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.accessToken").value(token))
                .andExpect(jsonPath("$.status").value("DEACTIVATE"))
                .andExpect(jsonPath("$.rank").value(1L));
    }
}​

이렇게 해서 Interceptor 테스트를 진행할 수 있었습니다~!

 

앞으로 남은 목표도 All Pass 입니다!

그리고 항상 노력하고 열심히하면서 지식을 많이 쌓고, 많이 배울 수 있었으면 좋겠습니다.

하나 더 얻어가고 싶은 건, 제가 개발할 때의 강점을 알 수 있게 되면 좋을 것 같습니다.

 

항상 같이 열심히 해준 우리 10조 팀원분들과, 코치님과 다른 팀원분들까지 모두 감사 드리고 긴 글 읽어주셔서 감사합니다~!

남은 기간 화이팅~~~!!!!!!!

 

 

제가 3주 동안 진행한 콘서트 예약 서비스 서버 구축 Github 링크 첨부합니다~~!

https://github.com/kdelay/Concert-Booking

 

GitHub - kdelay/Concert-Booking: 🎸 콘서트 예약 서비스

🎸 콘서트 예약 서비스. Contribute to kdelay/Concert-Booking development by creating an account on GitHub.

github.com

 

 

#항해플러스후기

#항해솔직후기

#항해플러스백엔드

 

항해 플러스 백엔드 신청 링크

https://hanghae99.spartacodingclub.kr/plus/be

 

항해 플러스, 도전을 넘어 개발자 커리어 도약으로

백엔드 주니어 개발자로서 성장의 한계를 느끼고 있다면, 시니어 코치진과 함께 10주 몰입을 통해 도약하세요.

hanghae99.spartacodingclub.kr

728x90
반응형

댓글