Mockito
- Mockito는 자바 진영에서 테스트를 위해서 사용되는 목킹 프레임워크 중 하나 입니다.
- Mock 들은 실 객체들을 대체 합니다.
- Dependency Injection과 궁합이 좋습니다.
Mock 어노테이션
- @Mock
- 목을 생성한다
- @Spy
- 스파이를 생성한다
- @InjectMocks
- 목과 스파이를 클래스에 주입한다
- @Captor
- argument를 캡쳐합니다.
Mock 생성하기
인라인으로 Mockito mock 생성
1
2
3
4
5
6@Test
void testInlineMock() {
Map mapMock = mock(Map.class);
assertEquals(mapMock.size(), 0);
}어노테이션으로 Mockito mock 생성
- @Mock 어노테이션을 사용해서 mock 객체를 생성할 수 있습니다.
- 이때, MockitoAnnotions.initMocks 를 해주지 않으면 mock 객체가 생성되지 않아, 테스트에서 mock 객체를 참조하는 경우 NullPointException이 발생합니다.
1
2
3
4
5
6
7
8
9
10
11
12@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
}
@Mock
Map<String, Object> mapMocks;
@Test
void testMock() {
mapMocks.put("keyvalue", "foo");
}
MockitoExtension을 통해 mock 생성
- MockitoExtension 을 사용할 수 있습니다. MockitoExtension의 beforeEach 메소드 내부에서
MockitoSession session = Mockito.mockitoSession().initMocks(testInstances.toArray()).strictness(actualStrictness).startMocking();
초기화 해주는 것을 확인 할 수 있습니다.1
2
3
4
5
6
7
8
9
10
11@ExtendWith(MockitoExtension.class)
public class JUnitExtensionTest {
@Mock
Map<String, Object> mapMock;
@Test
void testMock() {
mapMock.put("key", "value");
}
}
- MockitoExtension 을 사용할 수 있습니다. MockitoExtension의 beforeEach 메소드 내부에서
테스트 코드 작성해보기
아래와 같은 기본적인 CRUD를 지원하는 서비스가 있다고 해보겠습니다.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
31
32
33
34
35public class VisitSDJpaService implements VisitService {
private final VisitRepository visitRepository;
public VisitSDJpaService(VisitRepository visitRepository) {
this.visitRepository = visitRepository;
}
@Override
public Set<Visit> findAll() {
Set<Visit> visits = new HashSet<>();
visitRepository.findAll().forEach(visits::add);
return visits;
}
@Override
public Visit findById(Long aLong) {
return visitRepository.findById(aLong).orElse(null);
}
@Override
public Visit save(Visit object) {
return visitRepository.save(object);
}
@Override
public void delete(Visit object) {
visitRepository.delete(object);
}
@Override
public void deleteById(Long aLong) {
visitRepository.deleteById(aLong);
}
}
아래와 같이 서비스에 대한 테스트 코드를 작성해볼 수 있습니다.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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63@ExtendWith(MockitoExtension.class)
class VisitSDJpaServiceTest {
@Mock
VisitRepository visitRepository;
@InjectMocks
VisitSDJpaService visitSDJpaService;
@Test
void testFindAll() {
Visit visit1 = new Visit(1l);
Visit visit2 = new Visit(2l);
List<Visit> visits = Lists.list(visit1, visit2);
when(visitRepository.findAll()).thenReturn(visits);
Set<Visit> result = visitSDJpaService.findAll();
assertThat(result).hasSize(2);
verify(visitRepository).findAll();
}
@Test
void testFindById() {
Visit visit = new Visit(1l);
when(visitRepository.findById(1l)).thenReturn(Optional.of(visit));
Visit result = visitSDJpaService.findById(1l);
assertThat(result).isNotNull();
verify(visitRepository).findById(1l);
}
@Test
void save() {
Visit visit = new Visit(1l);
when(visitRepository.save(any(Visit.class))).thenReturn(visit);
Visit result = visitSDJpaService.save(new Visit());
assertThat(result).isNotNull();
verify(visitRepository).save(any(Visit.class));
}
@Test
void delete() {
Visit visit = new Visit(1l);
visitSDJpaService.delete(visit);
verify(visitRepository).delete(any(Visit.class));
}
@Test
void deleteById() {
visitSDJpaService.deleteById(1l);
verify(visitRepository).deleteById(anyLong());
}
}
Comments