Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 데이터분석
- 파이썬
- 데이터분석준전문가
- mickito
- SQLD단기합격
- 천안방탈출
- 천안데이트
- 백준
- 비전공자SQLD독학
- spting
- 태블로
- sqld
- Python
- 벡준1152
- listcomprehension
- Tableau
- ADsP
- ADsP공부
- BOJ10951
- 코딩테스트
- 데이터시각화
- 방탈출
- ADsP후기
- 자바
- SQLD노베이스
- SQLD독학
- SQLD공부
- 머신러닝
- SQL개발자
- 자율프로젝트
Archives
- Today
- Total
doistory
Unit Test에서 의존성 걱정 없이 테스트 작성 가능할까?: Mockito 와 BDDMockito 소개 본문
[ Devlopment ]/Spring
Unit Test에서 의존성 걱정 없이 테스트 작성 가능할까?: Mockito 와 BDDMockito 소개
떡볶이최고 2024. 10. 27. 16:52
1. Mockito
Mockito는 MIT 라이선스에 따라 출시된 Java용 오픈 소스 테스트 프레임워크
왜 써봐야 할까?
Spring은 DI(의존성 주입)을 통해 객체간 의존성을 관리 해준다.
그러나 이런 의존성은 테스트 시점에 문제를 발생시킨다. 특히 개발 단계에서 unit 테스트에 활용하기에 유용해보인다.
- Mockito는 Mock 객체를 용이하게 사용할 수 있도록 지원하는 테스트 프레임워크이다.
- 단위 테스트 시점에서 객체들의 의존관계 때문에 비즈니스로직에 대해 독립적으로 정확하게 작동하는 테스트 를 작성하기 어렵다.
- 즉 해당 객체에 대한 기능만 테스트 하려는데, 의존성 가지는 다른 객체가 테스트에 영향을 미친다.
- 이때 의존성을 가지는 객체들은 가짜(Mock)객체로 만들어 테스트 한다.
Mockito 간단 예제
Mock 객체에 원하는 동작을 미리 정하고 이를 기반으로 테스트 하게 된다.
아래는 간단한 사용 방법이다.
@ExtendWith(MockitoExtension.class)
class SmsServiceTest {
// Mock객체 생성
@Mock
private SmsCertificationRepository smsCertificationRepository;
// 의존성 주입
@InjectMocks
private SmsService smsService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void 테스트 {
// 테스트 작성
}
}
- @Mock 어노테이션을 사용해 Mock객체 생성
- @InjectMocks를 이용해 해당 클래스로 의존성 주입
2. Mockito vs BDDMockito
mock 객체를 활용한 테스트를 위해 두 가지 방법이 있다. 우리는 프로젝트에 BDDMockito를 채택하기로 했다.
각 함수 단위 테스트가 아니라 서비스의 흐름대로 테스트가 가능하기 때문이다.
따라서 코드를 읽어봄으로써 비즈니스 로직을 이해하기 용이한 장점이 있다고 생각했다.
Mockito
- mock 객체를 사용하여 when().thenReturn을 통해 테스트 코드를 작성한다.
- import org.mockito.Mockito
BDDMockito
- BDDMockito를 사용하면 given().willReturn()을 통해 테스트 코드를 작성한다.
- import org.mockito.BDDMockito
3. BDDMockito
- BDD는 Behavior-Driven Development (행위 주도 개발)을 말한다.
- BDD 행위 주도 개발 :
- 시나리오 기반으로 테스트. 즉 함수 단위 작성 X
- 테스트 대상의 상태 변화를 테스트 한다.
- 시나리오에 맞게 코드가 읽히도록 하는 목적. 비즈니스 요구사항에 집중하여 TestCase를 만드는 것.
- 무엇을 테스트할 것인가에 초점
- 권장 기본 패턴: Given, When, Then
- 테스트 대상이 T상태에서 출발하여(Given) 어떤 상태 변화를 가했을 때(When) 기대하는 상태로 완료되어야 한다.(Then)
- Side Effect가 전혀 없는 테스트 대상이라면 테스트 대상의 환경을 A 상태에 두고(Given) 어떤 행동을 요구했을 때(When) 기대하는 결과를 돌려받아야 한다. (Then)
- BDDMockito 클래스는 stub을 할 때 사용할 메소드로 BDDMockito.given(Object)를 제공
간단 예제
import static org.mockito.BDDMockito.*;
@ExtendWith(MockitoExtension.class)
class SmsServiceTest {
// Mock객체 생성
@Mock
private SmsCertificationRepository smsCertificationRepository;
@Mock
private SmsCertificationUtil smsUtil;
@Mock
private UserRepository userRepository;
@InjectMocks
private SmsService smsService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void 문자전송_성공() {
// Given (조건)
given(items.hasItems()).willReturn(true);
// When (기능 수행)
boolean actual = person.hasItem();
// Then (예상 결과)
assertThat(actual).isTrue();
}
후기
java, spring을 난생 처음 배우고 써보니 test는 전혀 생각하지 못했다. 수업 때도 테스트에 대해서 배우지 않았다.
SSAFY 프로젝트에서 메서드에 대해 단위 테스트를 하는 팀이 우리 팀 말고는 없다는 말을 들었다.
팀원 덕분에 테스트 코드를 작성해보며, 실제로 테스트가 왜 필요한지 알게 되었다.
테스트를 만들어보면서 여러가지 예외도 미리 생각을 하게 되었고, 오류 발생 가능한 지점도 미리 파악이 가능했다.
테스트를 통한 CI/CD를 도입하여 더욱 안정성 있는 프로그램을 작성할 수 있었다.
프론트 엔드 팀원들에게 오류 없는 API를 제공하여 칭찬을 받았다.
테스트 코드 작성은 어렵고 힘들었지만,,,,이렇게 팀 전체의 생산성을 높일 수 있었다.