yytbtb
@yytbtb9985
수강평 작성수
-
평균평점
-
블로그
전체 5#카테고리
- 백엔드
#태그
- 백엔드

2025. 06. 19.
0
워밍업 클럽 4기 백엔드 - Mock Test
1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 차이@Mock단순한 Mockito 목 객체 생성 (단위 테스트에 사용). Spring context와 무관.@MockBeanSpring context에 목 객체를 주입. 통합 테스트(@SpringBootTest 등)에서 사용. 기존 빈 교체.@Spy실제 객체를 감싸면서 특정 메서드만 mocking.@SpyBeanSpring context에 있는 빈을 Spy로 감싸서 주입.@InjectMocks해당 객체에 @Mock이나 @Spy로 선언된 의존성 주입.2. @BeforeEach, given절, when절 배치@BeforeEach void setUp() { 1-1. 사용자 생성에 필요한 내용 준비 1-2. 사용자 생성 1-3. 게시물 생성에 필요한 내용 준비 1-4. 게시물 생성 } @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기 백엔드 - Layered Architecture
💻 Presentation Layer1. 특징요청 수신과 응답 반환을 담당하는 계층.입력값의 유효성 검증을 책임지는 위치.2. 테스트 방법컨트롤러만 로드하는 @WebMvcTest 활용.서비스 계층은 @MockBean으로 대체한 의존성 주입.MockMvc를 사용한 API 호출 시뮬레이션과 응답 구조 검증.DTO에 적용된 validation 로직에 대한 테스트 포함.⚙ Business Layer1. 특징도메인 중심의 핵심 로직을 포함하는 계층.트랜잭션 처리와 비즈니스 흐름 제어를 담당하는 위치.2. 테스트 방법의존성을 모킹하여 단위 테스트로 분리한 로직 검증.@SpringBootTest를 통한 흐름 전체 테스트.트랜잭션 경계 설정을 위한 @Transactional 적용.예외 처리 및 동시성 상황에 대한 케이스 분리.🛢 Persistence Layer1. 특징데이터 저장소와 직접 통신하는 계층.Spring Data JPA 기반의 쿼리 메서드 정의와 실행 위치.2. 테스트 방법@DataJpaTest를 활용한 Repository 단위 테스트.H2 같은 인메모리 데이터베이스 기반의 독립 환경 구성.직접 작성한 쿼리에 대한 기능별 테스트 작성.(Practical Testing: 실용적인 테스트 가이드)
백엔드
・
백엔드

2025. 06. 15.
1
워밍업 클럽 4기 백엔드 - 3주차 발자국
3주차 회고✅ 미션 회고테스트 코드를 직접 작성해보는 과제가 주어졌다. 막상 손으로 써보니 예상보다 고민할 포인트들이 많았다. 테스트 설명을 어떻게 일관성 있게 작성할지, 테스트 단위의 크기를 어떻게 잡을지 등 단순히 "돌아가는 테스트를 만든다"는 차원을 넘는 고민들이 생겼다. 테스트를 작성하지 않았다면 미처 떠올리지 못했을 다양한 관점들을 경험할 수 있었던 좋은 기회였다.✅ 강의 회고스프링을 활용해서 간단한 기능들을 직접 만들어보고, 이에 대한 테스트를 TDD 방식으로 구현해 나가는 과정이 인상 깊었다. 테스트 코드 자체에 대한 설명도 좋았지만, 실무에서 마주칠 수 있는 동시성 이슈나 리팩토링 전략, 패키지 구조 같은 부분까지 언급해주셔서 실전 감각을 익히는 데 도움이 됐다. 무엇보다, 단순히 ‘이렇게 한다’가 아니라 ‘왜 이렇게 해야 하는지’를 같이 짚어줘서 더 깊이 있게 이해할 수 있었던 것 같다.✅ 학습 내용 요약Persistence Layer: CRUD에 집중, 비즈니스 로직 XBusiness Layer: 핵심 로직 구현, 트랜잭션 보장Presentation Layer: 요청 처리, 파라미터 최소 검증✅ 느낀 점늘 테스트 코드에 대한 부담감이 있었는데, 직접 TDD 방식으로 작성해보니 생각보다 자연스럽게 코드가 작성됐다. 이전에는 주로 비즈니스 로직에만 테스트를 작성했지만, 이번 기회를 통해 각 레이어 별로 테스트를 어떻게 구성해야 하는지도 알게 되었다. 특히 @DataJpaTest와 @SpringBootTest의 차이점처럼 기술적인 디테일을 짚어준 것도 좋았고, 지금 당장은 직접 적용하지 못하더라도 ‘이런 상황에서는 이런 고민을 할 수 있겠구나’ 하고 한 번 더 생각해볼 수 있는 포인트들을 많이 얻었다. 단순한 기능 구현을 넘어 코드의 구조나 품질을 고민하게 되는 계기가 됐다.(Practical Testing: 실용적인 테스트 가이드)
백엔드
・
백엔드
![워밍업 클럽 4기 - 백엔드 Day 4 [객체 지향 패러다임]](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2025. 05. 30.
0
워밍업 클럽 4기 - 백엔드 Day 4 [객체 지향 패러다임]
1. 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.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 class Item { private String name; private int quantity; private int unitPrice; public Item(String name, int quantity, int unitPrice) { this.name = name; this.quantity = quantity; this.unitPrice = unitPrice; } public int getQuantity() { return quantity; } public int getSubtotal() { return quantity * unitPrice; } }public class Order { private List items; private Customer customer; public Order(List items, Customer customer) { this.items = items; this.customer = customer; } public int getTotalItemCount() { return items.stream() .mapToInt(Item::getQuantity) .sum(); } public int getTotalPrice() { return items.stream() .mapToInt(Item::getSubtotal) .sum(); } public boolean isCustomerInfoEmpty() { return customer == null || customer.isEmpty(); } }public class Customer { private String name; private String email; public Customer(String name, String email) { this.name = name; this.email = email; } public boolean isEmpty() { return (name == null || name.isBlank()) && (email == null || email.isBlank()); } }public class OrderValidator { public void isValid(Order order) { if (isEmpty(order)) { System.out.println("주문 항목이 없습니다."); return; } if (isPriceInvalid(order)) { System.out.println("올바르지 않은 총 가격입니다."); return; } if (isMissingCustomerInfo(order)) { System.out.println("사용자 정보가 없습니다."); return; } System.out.println("유효성 검사를 통과했습니다."); } private boolean isEmpty(Order order) { return order.getTotalItemCount() == 0; } private boolean isPriceInvalid(Order order) { return order.getTotalPrice() 테스트public class AppRunner { public static void main(String[] args) { OrderValidator validator = new OrderValidator(); System.out.println("======= 주문 유효성 테스트 시작 ======="); Order emptyOrder = new Order(Collections.emptyList(), null); validator.isValid(emptyOrder); List items1 = List.of( new Item("노트북", 1, 1000000) ); Order noCustomerOrder = new Order(items1, null); validator.isValid(noCustomerOrder); List items2 = List.of( new Item("샤프", 1, -100) ); Customer customer1 = new Customer("홍길동", "hong@example.com"); Order negativePriceOrder = new Order(items2, customer1); validator.isValid(negativePriceOrder); List items3 = List.of( new Item("모니터", 2, 150000) ); Customer customer2 = new Customer("김철수", "kim@example.com"); Order validOrder = new Order(items3, customer2); validator.isValid(validOrder); System.out.println("======= 테스트 종료 ======="); } }2. SOLID에 대하여 자기만의 언어로 정리해 봅시다.SRP하나의 트레이에 하나의 물건을 담아야 정리하기 편하다.-> 클래스도 하나의 책임만 가져야 유지보수 편리OCP멀티탭에 새 기기 꽂는 것은 쉬운 데에 반해, 멀티탭 자체를 고치는 것은 힘들다.-> 기존 코드를 고치지 않고 기능을 추가할 수 있도록 설계LSP차를 렌트할 때, 차의 브랜드와 상관 없이 운전자는 차를 똑같이 운전할 수 있어야 한다.-> 부모(인터페이스)를 기준으로 만들어진 기능은, 자식 바꿔 끼워도 문제 없이 동작ISP스마트폰 사용자마다 필요한 어플리케이션만 다운 받아서 사용한다.-> 사용자가 쓰는 기능만 제공받도록 설계DIP이어폰을 바꾸어도 음악이 잘 들려야 한다.-> 고정된 구현이 나이라 추상적 연결(인터페이스)에 의존(Readable Code: 읽기 좋은 코드를 작성하는 사고법)
백엔드
![워밍업 클럽 4기 - 백엔드 Day 2 [추상과 구체]](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2025. 05. 27.
0
워밍업 클럽 4기 - 백엔드 Day 2 [추상과 구체]
추상과 구체운동하기운동복으로 갈아입기매트 위에서 스트레칭타이머 맞추기플랭크 30초스쿼트 20회물을 마시고 다음 세트 반복하기온라인으로 상품 구매쇼핑몰 사이트에 접속원하는 상품 검색상세 페이지 확인옵션 선택장바구니에 담기결제 정보 입력결제 버튼 클릭배송 정보 확인회의 준비회의 안건 정리발표 자료 정리회의실 예약참석자에게 초대장 발송발표 순서와 타이머 확인청소하기주변에 정리 되지 않은 옷이나 물건 치우기청소기로 바닥 먼지 빨아들이기걸레로 닦기세탁기 돌리기쓰레기 모아 분리수거 하기메서드를 추출하고 이름을 짓는 것에 있어서 많이들 그렇게 한다고 하고, 공통되게 사용되는 이름이 있다보니 관성적으로 코드를 짜왔는데 강의를 듣고 그 중요성을 알게 되었습니다.(Readable Code: 읽기 좋은 코드를 작성하는 사고법)
백엔드




