728x90
🔍 1. Mock이란?
✅ Mock은 "가짜 객체"를 말해
- 실제 의존 객체(여기선 ItemMapper)를 진짜로 실행하지 않고도,
테스트하고 싶은 코드(MyBatisItemRepository)만 단위로 따로 떼서 테스트할 수 있도록 도와주는 가짜 객체야.
package io.shi.dao.dao.mybatis;
import io.shi.dao.global.entity.Items;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
@Slf4j
@ExtendWith(MockitoExtension.class)
class MyBatisItemRepositoryTests {
@Mock
ItemMapper mapper;
MyBatisItemRepository repository;
@BeforeEach
void init(){
repository = new MyBatisItemRepository(mapper);
}
@Test
@DisplayName("상품등록서비스")
void item_save_test() throws Exception {
repository.save(null);
}
}
📦 지금 코드 기준으로 설명하면:
@Mock
ItemMapper mapper;
이건 진짜 DB와 연결된 MyBatis Mapper 객체가 아니라,
“이름만 ItemMapper처럼 생긴” 가짜(Mock) 객체를 생성한 거야.
이 가짜 객체는 내부적으로 아무 일도 하지 않고, 원하는 동작을 미리 정의해서 테스트 용도로만 사용해.
🔁 실제 흐름 분석
repository = new MyBatisItemRepository(mapper);
- 여기서 mapper는 진짜가 아니라 Mockito가 만든 가짜야.
- 이걸 MyBatisItemRepository에 주입함으로써, 테스트에서는 DB와 연결 없이 테스트가 가능해.
💥 Mock을 쓰는 이유
예시: 실제 DB 없이 테스트하기
만약 ItemMapper가 진짜라면, 내부에서 INSERT, SELECT 같은 DB 쿼리가 실행돼야 해. → 근데 테스트 환경에서 매번 DB와 연결하면 느리고, 복잡하고, 데이터도 꼬일 수 있음.
그래서 우리는 ItemMapper를 가짜로 만들어서 이런 DB 호출 없이도 repository 로직이 잘 작동하는지만 테스트할 수 있어.
🔧 @ExtendWith(MockitoExtension.class)
@ExtendWith(MockitoExtension.class)
이건 JUnit5에 Mockito 기능을 연결해주는 어댑터야.
- 이걸 붙여야 @Mock 같은 어노테이션이 제대로 작동돼.
- 없으면 @Mock으로 만든 객체가 주입되지 않아서 NullPointerException이 뜨게 돼.
🔍 Mock vs Stub vs Spy (간단 정리)
종류 | 설명 | 사용 예 |
Mock | 가짜 객체. 테스트 목적의 빈 껍데기 | 지금 코드의 @Mock ItemMapper |
Stub | 특정 상황에서 특정 값을 리턴하도록 정의 | when(mapper.save(any())).thenReturn(something) |
Spy | 진짜 객체를 감싸면서 일부만 가짜로 바꿈 | 실제 객체의 동작 확인 또는 부분 mocking |
🧪 너 코드에서 실제 테스트는?
@Test
@DisplayName("상품등록서비스")
void item_save_test() throws Exception {
repository.save(null);
}
이건 아직 검증은 안 들어간 상태고, 그냥 null을 넘기고 있어.
보통 이렇게 작성하지 않고, 아래처럼 동작을 지정해줘야 해:
예시
@Test
@DisplayName("상품등록 성공 테스트")
void item_save_test() throws Exception {
Items dummyItem = Items.builder()
.itemCode("ITEM_123")
.name("사과")
.price(1000)
.build();
// stub: mapper.save()가 호출되면 아무것도 안 하도록 처리 (void라면 doNothing)
repository.save(dummyItem);
// 이후에 mapper.save(dummyItem)이 정말 호출되었는지 검증할 수 있음
verify(mapper).save(dummyItem);
}
✅ 요약
요소 | 설명 |
@Mock | ItemMapper의 가짜 객체를 생성 |
MockitoExtension | Mockito의 기능을 JUnit5에서 활성화 |
Mock을 쓰는 이유 | DB 없이도 repository 로직만 독립적으로 테스트 가능 |
verify() | mock 객체가 호출됐는지 검증 가능 (테스트 정확도 ↑) |
728x90
'프로그래밍 > Spring' 카테고리의 다른 글
JPA- 4월 10일 (0) | 2025.04.10 |
---|---|
Mock란? - 4월 10일 (1) | 2025.04.10 |
MyBatis란? (0) | 2025.04.09 |
🌟 트랜잭션(Transaction) 이란? (0) | 2025.04.09 |
JDBC를 이용한 간단한 CRUD 구현 (0) | 2025.04.08 |