![[인프런 워밍업 클럽 3기] BE 클린코드&테스트 - 4주차 발자국](https://cdn.inflearn.com/public/files/blogs/dd713d31-50dd-4eca-b101-ac68cdd20690/스크린샷 2025-03-16 오후 11.53.00.png)
[인프런 워밍업 클럽 3기] BE 클린코드&테스트 - 4주차 발자국
💡 강의 핵심 내용 정리
💻Practical Testing
🔹 1. 왜 Mocking이 필요한가?
외부 시스템(메일 전송, 결제, 알림 등)을 호출하는 코드는 실제 실행하면 부작용이 발생할 수 있음.
테스트 시 외부 의존성을 제거하고 예측 가능한 결과를 주기 위해 Mock 객체를 사용함.
이 과정을 Stubbing이라 하며, 원하는 동작을 가짜 객체에게 명시함.
Mockito.when(mailSendClient.sendEmail(...)).thenReturn(true);
🔹 2. Mail 전송은 @Transactional을 붙이면 안 되는 이유
메일 전송은 외부 네트워크 요청이며, 트랜잭션 범위 안에서 실행되면 DB Connection을 오래 점유하게 됨.
이런 긴 작업은 트랜잭션 바깥에서 실행되어야 함.
🔹 3. Test Double의 종류
유형 설명 Dummy 사용되지 않는, 껍데기 객체 Fake 간단한 구현을 가진 실제 객체 (Map
기반 Repository 등) Stub 미리 정의된 응답을 제공하는 객체 (상태 검증용) Spy 일부는 실제처럼, 일부는 Stub. 호출 기록 추적 가능 Mock 행위 기반 검증용 객체 (몇 번 호출되었는지 등 검증)
💡 Stub은 상태 검증, Mock은 행위 검증에 사용됨.
🔹 4. 순수 Mockito 사용법
@Mock
,@InjectMocks
,@ExtendWith(MockitoExtension.class)
조합으로 Spring Context 없이도 테스트 가능@Spy
: 실제 객체 기반으로 필요한 부분만 Stubbing
doReturn(true).when(mailSendClient).sendEmail(...);
🔹 5. BDDMockito
when(...).thenReturn(...)
대신 Given-When-Then 스타일을 지향
BDDMockito.given(mailSendClient.sendEmail(...)).willReturn(true);
테스트의 목적과 구조가 명확하고 선언적으로 표현됨.
🔹 6. Classicist vs Mockist
구분 Classicist Mockist 테스트 단위 실제 객체로 통합 테스트 협력 객체는 모두 Mock 강조점 시스템 동작 검증 객체 간 상호작용 검증 사용 시점 DB, HTTP 연동 등 진짜 동작 필요할 때 외부 의존이 많거나, 로직 복잡도 높은 객체
✅ 일반적으로는 Classicist 접근을 사용하고, 외부 시스템 등 불가피한 경우에만 Mocking을 하자!
🔹 7. 테스트 코드 개선 전략 요약
📌 한 문단에는 한 주제
테스트는 명확하게 하나의 동작만 검증해야 함.
if
,for
등의 분기/반복문이 테스트 코드에 들어가면 테스트 목적이 흐려짐.
📌 제어 가능한 값만 사용하라
현재 시간
,UUID
,랜덤
,환경 변수
등은 직접 주입하거나 인터페이스로 추출하여 테스트 가능하게 설계.
📌 테스트 간 독립성 보장
static 공유 객체 금지 (
@BeforeAll
/@BeforeEach
도 주의)fixture는 되도록 각 테스트 내에서 명시적으로 구성
📌 Test Fixture는 생성자 기반 / Builder 활용
팩토리 메서드 대신 Builder 패턴 선호
data.sql
로 데이터 주입 지양 → 테스트 목적 파악 어려움
📌@ParameterizedTest
, @DynamicTest
적극 활용
경계값, 다양한 조건 검증이 필요한 경우 유용
@DynamicTest
는 상태 변화 시나리오 테스트에 특히 적합
📌 공통 테스트 환경 통합
@SpringBootTest
를 반복 호출하지 않도록 상위 추상 클래스로 환경을 공통화
@SpringBootTest
@ActiveProfiles("test")
public abstract class IntegrationTestSupport {}
📌 private 메서드는 테스트하지 말자
테스트가 필요할 정도로 복잡해졌다면, 새로운 객체로 추출해서 테스트 가능하도록 리팩토링.
댓글을 작성해보세요.