블로그
전체 42025. 03. 30.
0
인프런 워밍업 클럽 스터디 3기 - 백엔드 코드 4주차 발자국
강의 수강섹션7. Mock프로젝트할 때, 다른 팀원이 mock을 이용해 테스트코드 짠것을 보고 살짝 느낌만? 이해해서 테스트를 작성한 경험이 있다. 이번 강의를 수강하면서, stubbing을 한다라는 개념을 이해하고 내가 작성했던 코드를 더 잘 이해할 수 있게 되었다.Mock vs StubMock은 Stub이 아니다.Mock : 행위에 대한 기대를 명세하고 그에 따라 동작Stub : 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공. 그 외에는 응답하지 X둘의 차이는Stub의 목적은 상태 검증Mock의 목적은 행위 검증Mock vs SpySpy란? 객체에서 일부는 Stubbing 하고 싶고, 일부는 실제 객체 동작처럼 하고 싶을때는 Spy를 사용한다.참고디비는 트랜잭션이 끝날때까지 커넥션을 가지고 있는데 메일전송같은 네트워크를 타거나 긴 작업의 경우에는 트랜잭션을 걸지 않는 것이 좋다.섹션8. 더 나은 테스트테스트 간 공유하는 변수같은 공유자원은 쓰지 말자. 각 테스트에서 given 데이터가 겹치는 경우가 많다.중복 제거하려고 beforeach나 beforeall에서 공유 변수들을 생성하려고 하는 경우가 있는데, 이거는 지양하자.이유-> 테스트 간 결합도를 높인다.-> 각 테스트를 이해할 때 자꾸 스크롤하면서 봐야됨.그럼 beforeeach는 언제?각 테스트 입장에서 봤을 때, 아예 몰라도 테스트 내용을 이해하는 데에 문제가 없는가?수정해도 모든 테스트에 영향을 주지 않는가?이 두 조건을 만족하면 beforeach에 있어도 됨.TextFixtur 클렌징deleteAll()order만 지워도 orderProduct까지 같이 지워진다.-> 성능 이슈가 있을 수 있다.엔티티 삭제 순서 고려 해야함.테스트도 비용이기 때문에, deleteAll()은 훨씬 비용이 크다. 그래서 강사님은 deleteAllInBatch() 선호함.이외 유용한 테스트 방법@Parameterized값이나 환경을 바꿔가면서 테스트를 확장하고 싶을 때 사용@DaynimicTest 하나의 환경을 설정하고, 사용자 시나리오를 테스트하고 싶을 때.환경에 변화를 주면서 중간 중간 검증을 하고 싶을 떼 사용테스트 비용같은 스프링부트테스트여도, profile 차이나 환경이 조금만 달라져도 다시 스프링부트가 실행된다. -> 실행 속도 느려짐.테스트 환경 통합하자.private 메소드는 테스트할 필요 X테스트 해야될 거 같으면 객체 분리 필요한지 생각해보고, 분리해서 테스트 수행섹션9. Spring REST Docs스웨거만 사용해봤었는데, 나중에 REST Docs도 프로젝트에 적용해봐야겠다.REST Docs장점 :테스트를 통과해야 문서가 만들어진다.프로덕션 코드를 건드리지 않고 문서 작성 가능단점:코드 양이 많다.설정이 어렵다. Swagger장점 :적용이 쉽다.문서에서 바로 API 호출을 수행해볼 수 있다.단점 :프로덕션 코드를 수정해야 한다.테스트와 무관해서 신뢰도가 떨어진다.미션Day16강의를 수강하면서 짬뽕처럼 뒤섞여 있던 각 레이어별 테스트가 과제를 통해 내용을 적어보면서 머리에서 비교적 정리가 된 것 같다. 그리고 통합테스트, 단위테스트, mock 테스트에 대해 정리해보면서 각 테스트에 대한 개념과 차이에 대해 이해할 수 있었다. 나중에 공부한 내용을 까먹더라도, 테스트할 때 어떤 테스트를 수행할지 찾아보고 적합한 테스트를 골라서 테스트코드를 작성할 수 있을 것이다.Day18강의를 들으면서는 mock과 spy 차이에 대해서만 인지했다. 과제 수행을 위해 인터넷을 뒤져가며 공부를 한 끝에 @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이에 대해 알 수 있었다. 이제 필요한 때에 적절한 mock이나 spy, injectmocks를 사용할 수 있게 되었다. 그리고 given, when, then에 맞추어 테스트 명령어를 정리하는 실습을 통해 시나리오에 맞추어 테스트를 수행한다라는 개념을 이해하게 된 것 같다.
2025. 03. 22.
0
인프런 워밍업 클럽 스터디 3기 - 백엔드 코드 3주차 발자국
강의 수강섹션3. 단위 테스트이전에 프로젝트에서도 사용해본 적이 있는 단위테스트와 JUnit에 대해 배웠다. 해본 적이 있지만, 다시 막상 보니 새롭게 느껴져서 복습하듯이 학습했다.테스트하기 어려운 영역에 대해, 이전에는 해당 테스트는 그냥 사람이 직접 테스트하는 것으로 구현했었다. 하지만 이번 강의를 통해 밖으로 파라미터를 주입시켜주어 순수 함수로 만들어주면, 테스트 코드를 작성할 수 있다는 것을 알게 되었다.섹션4. TDDTDD를 이론으로만 공부해봤지 직접 코드를 작성하는 것은 처음이었다. 이론으로만 배웠을 때는 너무 멀게만 느껴졌는데, 직접 코드를 따라치니까 더 TDD가 무엇인가에 대한 개념이 가까워지는 것 같다.TDD 코드를 따라치면서 느낀 것이, TDD를 지키지 않고 개발할 때보다 코드 파일들을 많이 왔다갔다 하는 것이라고 체감이 들었다. TDD를 지킬 때에는 내가 무엇을 개발하고 있었는가에 대해 계속 의식해주어야 될 것같다는 생각이 들었다. 강의를 들을 때에는 사용하지 않았지만, 내가 직접 TDD를 스스로 한다면, Red Green refactor을 하는 과정에 주석에 todo 표시를 자꾸 해줘야 되겠다.섹션5. 테스트는 [ ]다.👍 DisplayName을 "ㅇㅇ 테스트"라고 명명하는 습관이 있었는데, 강의 시작하자 마자 지적받아서 뜨끔했다. 이제 절대로 저렇게 작명하지 않을 것이다.👍 given, when, then을 나누어 작성하는 BDD에 대해 배웠다. 아직 given, when, then에 어떤 명령어가 해당 되는지 헷갈려서 익숙치 않다. 계속 연습해봐야겠다.섹션6. Spring & JPA 기반 테스트👍 @SpringBootTest와 @DataJpaTest 의 가장 큰 차이는 @DataJpaTest는 @Transactional을 포함하고 있다는 것이다.@SpringBootTest에 @Transactional 추가해주면, @AfterEach 함수로 데이터 초기화 안해줘도 되는데 이러면 서비스 클래스에 @Transactional이 안붙어있어도 테스트코드가 통과되는 문제가 있다. 이거 알고 쓰자.👍 서비스 클래스에 @Transactional(readonly = true) 를 걸고, CUD 메소드에 한해서 @Transactional 을 해주자.👍 ㅇㅇ 생성 함수에서는 동시성을 고려해주어야 한다.함수가 호출되는 빈도수가 낮으면? 👉 ㅇㅇ의 id에 unique 제약조건 걸고, 실패 시 재시도하는 로직을 추가함수 호출 빈도가 높으면? 👉 ㅇㅇ의 id를 +1씩 증가하는 값이 아니라, UUID같은 것으로 대체미션Day11역시 저번 실습 미션처럼 강의를 보며 따라칠때는 너무 쉬운 것 같은데 직접 치려니 힘들다. 특히 어떤 메소드에 대해 테스트코드를 작성해야하는가 판단하는 부분이 가장 어려웠다.이미 구현 코드는 작성되어 있으니 given, when, then을 나누어 DDD를 지켜 코드를 작성했다. 각 명령어들이 given, when, then 어느쪽에 속해있는지 판단하는 것이 아직 어렵다. 그래도 강의 맨 처음에 지적받은 DisplayName 명명 규칙은 열심히 지킨 것 같다.
백엔드
2025. 03. 16.
0
인프런 워밍업 클럽 스터디 3기 - 백엔드 코드 2주차 발자국
강의 수강섹션 6. 코드다듬기주석이 필수적인 코드는 개발자의 의도를 잘 넣지 못한 코드다. 필요 이상의 주석이 필수적이라면 코드를 다시 고쳐야한다.👍 좋은 주석 : 최선을 다했지만, 코드로 개발자의 의도를 표현할 수 없을 경우 작성하는 주석메서드 순서는 공개 메서드부터 private 메서드 순서로, 중요한 순서가 먼저 나오도록 정리하자. 섹션 8. 기억하면 좋은 조언들복잡하고 엉망인 코드를 이해하려 할때는 리팩토링하면서 읽자. ( 뭔가 잘못됬다면? git reset --hard로 되돌리기 )👍 오버 엔지니어링 : 필요한 적정수준보다 더 높은 수준의 엔지니어링구현체가 하나인 인터페이스는 애플리케이션이 비대해진다. 과도한 추상화는 후대 개발자들이 선대의 의도를 파악하기 힘들어진다.만능 해결사 같은 기술은 없다. 👍 지속 가능한 소프트웨어의 품질 vs 기술 부채를 안고 가는 빠른 결과물회사의 사정에 의해 품질을 챙기지 못할 수도 있고, 때로는 오래된 기술이 우리 팀에 더 잘 맞을 수 있다.적정 수준에서 줄다리기를 잘하자. 미션Day7강사님을 따라 코드를 작성할 때는 끄덕끄덕 거리면서 작성했는데, 내 것으로 체화되지는 않았는 것 같다. 막상 코드를 리팩토링하려니 어디서부터 해야할지 어려움이 있었다. 이전 과제에서 수행했던 것처럼, early return, 예외 처리, 메소드 분리부터 리팩토링하고, 메소드를 공개메소드부터 중요한 순으로 정리했다. 새로운 도메인 개념을 추출하는 것은 시도도 하지 못했다. 강의를 다시 보면서 코드를 리팩토링하는 과정을 완전히 이해할 수 있도록 해야될 것 같다.
백엔드
2025. 03. 09.
0
인프런 워밍업 클럽 스터디 3기 - 백엔드 코드 1주차 발자국
강의 수강섹션2. 추상평소 개발 공부를 하면서 "추상화를 해야한다"를 막연히 알고 있을 뿐 진지하게 생각해본 적이 없는 것 같다.추상과 구체, 그 사이에 추상화 레벨이 존재한다는 것을 배웠다.특히 코딩테스트할 때 변수명으로 count 대신 cnt를 많이 선택했는데, 클린 코드에서는 권장하지 않는다는 내용에 뜨끔했다.섹션3. 논리, 사고의 흐름코드를 이해하기 위해 사용하는 뇌 메모리를 적게 써야한다는 것을 배웠다.중첩 for문은 줄일 수 있으면 좋다는 내용은 알고 있었다. 하지만 if문, else if문, else문 구조와 부정어를 많이 사용했고 이런 코드가 좋지 않은 코드인지 알지 못했다.어려운 방법이 아니니까 앞으로 프로그래밍할 때 부터 적용해봐야겠다.섹션4. 객체 지향 패러다임👍 SRP : 하나의 클래스는 단 하나의 책임만을 가져야 한다.👍 OCP : 확장에는 열려있고 수정에는 닫혀있어야 한다.👍 LSP : 부모 클래스를 자식 클래스로 바꿀 수 있어야 한다.👍 ISP : 필요한 인터페이스만 제공해야 한다.👍 DIP : 구현 클래스말고 인터페이스에 의존해야 한다.섹션5. 객체 지향 적용하기👍 상속보단 조합 이용한다.👍 VO는 식별자가 없지만, Entity는 식별자가 존재한다.👍 변경이 너무 잦으면 Enum보단 DB로 관리한다.👍 추상화와 다형성 활용해서 반복되는 if문 제거한다. 미션Day2먼저 추상화와 구체에 대한 개념을 머릿속에서 정리해보았다. 이후 일상에서 떠오르는 구체와 추상화의 예시를 떠올리며 추상의 레벨에 대해서도 생각해보았다.Day4코드를 살펴보며 내가 적용할 수 있는 early return, 중첩 반복문 제거와 메소드 분리 등을 하나씩 차례로 적용해보았다. SOLID의 원칙을 강의에서 적용한 코드를 살펴보며 내가 다시 봤을 때 잘 알아볼 수 있는 한마디로 표현하고자 생각하는 시간을 가질 수 있었다. 나중에 동료가 스파게티 코드를 짜면 멋지게 고쳐주는 개발자가 되고 싶다.
백엔드