블로그
전체 8#카테고리
- 백엔드
#태그
- 워밍업클럽4기
- 백엔드
2025. 06. 22.
3
[워밍업 클럽 4기] 백엔드 4주차 발자국
✅ 강의 수강Test Double : Dummy, Fake, Stub, Mock, SpyMocking을 사용하는 시점?외부 시스템을 대체하고 싶은 경우 더 나은 테스트를 작성하는 법한 문단에 한 주제만 가지기테스트 상황에 따라 결과가 달라질 수 있는 값 X테스트 환경 통합해서 관리하는 법Test Fixture 구성하기✅ 미션Day 16각 Layer 별 특징 및 Test 방법 정리Day 18도메인 관점에서 생각하자! 4주차 강의 회고두 강의를 완강하면서 어떤게 클린 코드인지 알 수 있게 되었다. 실무에서는 trade-off 를 잘 고려하면서 코드를 짜야 겠다. 또한 테스트 코드에 막연한 두려움을 가지고 있었는데, 각 레이어별 테스트 코드를 어떻게 구성하는지와 Mocking을 어느 상황에 해야되는지 등 다양한 지식을 학습할 수 있었다. 배운 개념들을 열심히 복습해서 내 것으로 만들 수 있도록 하겠습니다.
백엔드
2025. 06. 20.
1
워밍업 클럽 4기 백엔드 - [Day 18 미션]
미션 내용1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이를 한번 정리해 봅시다.@MockSpring Context와 무관실제 객체 대신 가짜(mock) 객체 생성@Spy일부는 실제 객체처럼 , 일부는 Stubbing이 가능@InjectMocks테스트 대상 객체에 필요한 Mock들을 자동 주입@MockBeanSpring Context에 등록된 기존 Bean을 Mock으로 교체전체 애플리케이션 컨텍스트가 필요한 통합 테스트에서 주로 사용 @SpyBeanSpring Context에 등록된 기존 Bean을 Spy로 교체 아래 3개의 테스트가 있습니다. ✔ 게시판 게시물에 달리는 댓글을 담당하는 Service Test✔ 댓글을 달기 위해서는 게시물과 사용자가 필요하다.✔ 게시물을 올리기 위해서는 사용자가 필요하다.내용을 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요?(@BeforeEach에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach에 배치)@BeforeEach void setUp() { 사용자 생성에 필요한 내용 준비 사용자 생성 게시물 생성에 필요한 내용 준비 게시물 생성 } @DisplayName("사용자가 댓글을 작성할 수 있다.") @Test void writeComment() { // given 1-5. 댓글 생성에 필요한 내용 준비 // when 1-6. 댓글 생성 // then 검증 } @DisplayName("사용자가 댓글을 수정할 수 있다.") @Test void updateComment() { // given 2-5. 댓글 생성에 필요한 내용 준비 2-6. 댓글 생성 // when 2-7. 댓글 수정 // then 검증 } @DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.") @Test void cannotUpdateCommentWhenUserIsNotWriter() { // given 3-3. 사용자2 생성에 필요한 내용 준비 3-4. 사용자2 생성 3-7. 사용자1의 댓글 생성에 필요한 내용 준비 3-8. 사용자1의 댓글 생성 // when 3-9. 사용자2가 사용자1의 댓글 수정 시도 // then 검증 } 출처 : 🔗Practical Testing: 실용적인 테스트 가이드
백엔드
2025. 06. 17.
0
[워밍업 클럽 백엔드 4기] Day 16 미션
Persistence Layer특징:Data Access의 역할비즈니스 가공 로직이 포함되면 안됨.테스트 방법작성한 쿼리나 JPA 쿼리가 의도대로 동작하는지 테스트한다.데이터가 실제로 DB에 저장되고 조회되는지 테스트한다.@ActiveProfiles를 사용해 테스트 전용 DB를 따로 두어 테스트한다.@DataJpaTest 사용시 자동으로 롤백된다. (@Transactional) Business Layer특징:비즈니스 로직 구현트랜잭션 보장해줘야 함.동시성 고민테스트 방법@SpringBootTest 어노테이션을 이용해 실제 환경과 비슷한 환경에서 테스트 진행요구사항 추가에 따른 도메인 로직 및 Repository 추가 및 변경이 이뤄지는데 각 케이스마다 테스트 작성 필요하다.경계값이 주어져도 정상적으로 동작하는지 테스트 Presentation Layer특징:외부 세계의 요청을 가장 먼저 받는다.파라미터에 대한 최소한의 검증을 수행한다.테스트 방법@WebMvcTest 어노테이션 이용나머지 의존성은 Mocking을 사용해 주입 후 테스트 진행validation, 상태 코드, JSON 응답 구조를 확인한다. 강의 출처 :Practical Testing: 실용적인 테스트 가이드
백엔드
・
워밍업클럽4기
2025. 06. 15.
1
[워밍업 클럽 4기] 백엔드 3주차 발자국
📗강의 회고스프링 핵심 개념Ioc, DI, AOPPersistence LayerData Access의 역할비즈니스 가공 로직이 포함되면 안됨.Business Layer비즈니스 로직 구현트랜잭션 보장해줘야 함.동시성 고민Business Layer는 Persistence Layer에 의존하므로 통합테스트가 필요하다.Presentation Layer외부 세계의 요청을 가장 먼저 받는다.파라미터에 대한 최소한의 검증을 수행한다. @Transactional을 쓸 때 Command와 Query를 분리하기Command상태를 변경하는 작업(Create,Update,Delete)Query상태를 조회하는 작업(Read)@Transactional(readOnly 옵션) 🔥 미션 회고지뢰찾기 프로젝트를 선택해 단위 테스트를 작성했다.이미 작성돼있는 코드를 바탕으로 테스트를 작성하다보니, 일부 작성하기 어려운 테스트 코드가 있었다.테스트 코드가 돌아가게 만들기 위해 클린코드에서 멀어지게 되다보니 어려웠. 이 부분은 테스트 코드 강의 수강 후 복습하면서 고민해봐야 겠다.또한 다른 분들의 리팩토링, 테스트 코드 작성 미션을 보면서 새로운 관점들을 많이 배울 수 있었다.
백엔드
・
워밍업클럽4기
2025. 06. 08.
1
[워밍업 클럽 4기] 백엔드 2주차 발자국
📗강의 수강읽기 좋은 코드 강의를 마무리하였습니다.테스트 코드 강의 섹션 1~5를 진행 중입니다.🔥 미션 Day 7 리팩토링 미션을 진행하였다.배웠던 강의 내용과 강사님이 적어주신 리팩토링 주제를 참고하여 최대한 적용하려고 해보았다. 중간 점검 때 다른 수강생분들의 코드와 비교해볼 수 있어서 좋았다. 다 적용하진 못했지만 그래도 강의에서 배운 것들 중 일부는 잘 적용한 거 같았다.추후 강사님 강의와 비교해 부족한 점을 학습할 수 있었다.리팩토링의 어려운 점은 정답은 없지만, 나쁜 코드는 존재한다는 것이다. 리팩토링을 해나가는 자연스러운 흐름이 아직은 어려운 거 같다. 전체적인 추상화 레벨을 맞추어서 개선해나가야하는데 아직은 하나의 기능을 리팩토링 하는데 매몰되다 보니 주변 코드들과의 추상화 레벨을 맞춰가며 리팩토링을 진행했던 거 같지 않다.😃 다짐테스트 코드 강의도 열심히 수강해보겠습니다!다음 테스트 코드 미션 코드 리뷰에는 신청 해보겠습니다!
백엔드
・
백엔드
2025. 06. 01.
1
[워밍업 클럽 4기 - 백엔드] 1주차 발자국
1주차 회고 개념을 배우고 적용하면서 좋은 코드를 작성하는 법을 배울 수 있었다.다만 배운 개념을 코드에 적용시킬 수 있기 위해선 많은 노력이 필요할 거 같다.이번주에는 섹션 4까지 수강했는데 섹션2와 섹션 3에서는 읽기 좋은 코드를 만들 수 있는 다양한 내용을 배웠다.섹션4에서는 객체 지향 패러다임의 유명한 법칙인 SOLID를 배우면서 실습도 해보았다. 2주차 다짐섹션 6까지 배운 내용으로 섹션7에서 직접 배운 개념을 적용해볼 수 있을 거 같은데 배운 내용을 열심히 복습해보도록 하겠습니다.
백엔드
2025. 05. 30.
0
[백엔드 4기] Day 4 미션 제출
1. 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다. ✔ 사용자가 생성한 '주문'이 유효한지를 검증하는 메서드. ✔ Order는 주문 객체이고, 필요하다면 Order에 추가적인 메서드를 만들어도 된다. (Order 내부의 구현을 구체적으로 할 필요는 없다.) ✔ 필요하다면 메서드를 추출할 수 있다. As Ispublic boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }To Bepublic boolean validateOrder(Order order) { if (order.isEmpty()) { log.info("주문 항목이 없습니다."); return false; } if (order.isWrongTotalPrice()) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.isCustomerInfoMissing()) { log.info("사용자 정보가 없습니다."); return false; } return true; }2. SOLID에 대하여 자기만의 언어로 정리해 봅시다. SRP 하나의 클래스는 단 한 가지의 변경 이유만을 가져야 한다.한 객체를 변경했을 때 다른 객체가 영향을 받으면 안됨OCP확장에는 열려 있고, 수정에는 닫혀 있어야 함.새로운 기능을 추가한다 했을 때 기존에 있던 코드에 영향을 최소화 해야 함.LSP상속 관계에 있을 때 자식은 부모의 역할을 완벽하게 대신할 수 있어야 함.부모에 자식 클래스를 갖다 놨을 때 오류가 발생하면 안 된다.ISP클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.따라서 인터페이스는 하나의 기능만 담당하게 잘게 쪼개야 한다. 인터페이스 기능 중 사용하지 않는 게 있다면 안티패턴이다.DIP상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안된다.상위 수준의 모듈과 하위 수준의 모듈 모두 추상화된 것에 의존하면 된다.
백엔드
・
백엔드
2025. 05. 28.
0
[백엔드 4기] 2주차 미션 제출
추상 : 사용자가 브라우저에 주소를 입력하고 웹페이지에 접속한다. 구체 : 사용자가 주소창에 주소를 입력 후 접속한다.웹 브라우저나 OS의 내부 DNS 캐시에 도메인 이름의 IP 주소가 있는지 확인한다.존재하면 캐시에서 가져오고, 없으면 DNS 서버에게 IP 주소를 받아 온다.HTTP 요청 메시지를 생성 한다.SOCKET 라이브러리를 통해 서버와 TCP/IP 연결을 맺는다.데이터를 패킷 형태로 만들고, 네트워크를 통해 서버측에 전달한다.서버측에 패킷이 도착하면 데이터를 꺼내고 HTTP 메시지를 해석한다.서버측에서 HTTP 응답메시지를 생성 후 사용자에게 전달한다.
백엔드
・
백엔드
・
워밍업클럽4기