4/09/2024

BBMockito vs. Mockito

Mockito

Mockito는 모의(Mock) 객체를 편하게 사용하도록 지원해주는 테스트 프레임워크이다. 모의 객체는 의존성을 가지는 객체를 이름 그대로 모의하여 원하는 동작만 하도록 만들어진 객체이다. @Mock 어노테이션을 사용하여 모의 객체를 생성할 수 있고 @InjectMocks 어노테이션을 사용하여 모의 객체를 생성하고 @Mock 어노테이션으로 지정된 모든 모의 객체를 주입할 수 있다(즉, 의존성 주입). 


BDDMockito

BDD는 Behavior-Driven-Development의 약자로 행위-주도-개발을 의미한다. 테스트 대상의 상태의 변화를 테스트하고 시나리오를 기반으로 테스트하는 패턴(given, when, then)을 권장한다. 테스트 대상이 특정 상태(given)에서 출발하며 어떤 상태 변화를 적용 했을 때(when) 기대하는 상태로 되어야 한다(then). BDDMockito는 Mockito을 상속한 클래스로  동작이나 사용법에서 Mockito와 차이가 거의 없다. 즉, BDDMockito는 BDD를 사용하여 테스트 코드를 작성할 시 시나리오에 맞게 테스트 코드가 읽힐 수 있도록 도와주는 테스트 프레임워크이다.
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
// Mockito 클래스를 확장해서 의존성을 모의하기 위해 주석을 사용하는 것을 이해한다.
@ExtendWith(MockitoExtension.class)
public class PostServiceTest {
 
    // @Mock 어노테이션을 사용하여 모의 객체를 생성할 수 있다. 
    // mock() 메서드를 여러 번 호출하는 대신 모의 객체를 여러 곳에서 사용하고자 할 때 유용하다.
    @Mock
    private PostRepository postRepository;
    
    // @InjectMocks 어노테이션을 사용하여 모의 객체를 다른 모의 객체에 주입한다. 
    // @InjectMocks 어노테이션은 모의 객체를 생성하고 그 안에 @Mock 어노테이션으로 지정된 모든 모의 객체들을 주입한다.
    @InjectMocks
    private PostServiceImpl postService;
    
    private PostDto.Request postDto;
    private PostEntity postEntity;
    private PageDto pageDto;
    
    // @BeforeEach 어노테이션이 있는 메서드는 테스트 케이스가 실행되기 전에 실행된다.
    @BeforeEach
    public void setUp() {
        // mock() 메서드로 PostRepository 인터페이스의 모의 객체를 생성한다.
        // postRepository = Mockito.mock(PostRepository.class);
        // postService = new PostServiceImpl(postRepository);
        
        Long id = 1L;
        String title = "테스트";
        String description = "테스트 포스트";
        String content = "테스트를 위한 포스트";
        
        postDto = new PostDto.Request(title, description, content);
        postEntity = new PostEntity(id, title, description, content);
        pageDto = new PageDto();
    }
    
    @DisplayName("포스트 서비스의 create() 메서드로 포스트 생성 성공 테스트")
    @Test
    public void givenPost_whenSavePost_thenReturnSavedPost() {
        // org.mockito.exceptions.misusing.PotentialStubbingProblem 오류.
        // Mockito 2.20부터 lenient() 메서드로 Mockito의 기본 행동인 strict stub을 변경한다.
        // BDDMockito 클래스는 메소드를 설정된 응답을 반환하도록 스텁(stub)한다.
        // BDDMockito.lenient().when(postRepository.save(any(PostEntity.class))).thenReturn(postEntity);
        BDDMockito.given(postRepository.save(any(PostEntity.class))).willReturn(postEntity);
        
        ApiResponse<PostDto.Response> response = postService.create(postDto);
                
        Assertions.assertEquals(response.getMetadata().getCode(), Code.CREATED.getCode());
        Assertions.assertEquals(response.getData().getId(), 1);
        
        BDDMockito.then(postRepository).should(BDDMockito.times(1)).save(any(PostEntity.class));
    }
}
cs

update: 2024.04.09