본문 바로가기
🌱BackEnd/Spring

[SPRING] BDD란?

by Dong Ik 2023. 6. 21.

Mock이란?

Mock 객체는 테스트에서 실제 객체를 대신하여 사용되는 가짜 객체입니다. 테스트 중에 호출되는 메서드의 반환 값을 지정하거나 예외를 발생시키는 등의 동작을 모방하여, 의존하는 다른 객체에 영향을 받지 않고 독립적으로 테스트할 수 있습니다.

 

Spring 프레임워크에서는 Mock 객체를 사용하여 다른 구성 요소와 상호작용하는 코드를 테스트할 수 있습니다. 예를 들어, Spring MVC 컨트롤러를 테스트할 때는 MockMvc 객체를 사용하여 HTTP 요청을 보내고 응답을 검증할 수 있습니다.

MockMvc는 실제 HTTP 요청을 처리하는 대신 가상의 요청을 처리하여 컨트롤러를 테스트하는 데 사용됩니다.

 

 

BDD란?

BDD란 Behavior Driven Development의 약자로써 행위 주도 개발입니다.

BDD는 기능이나 동작을 가진 테스트 케이스를 작성하여 소프트웨어를 개발하는 방법을 강조합니다. 테스트 케이스는 "given-when-then" 구조를 따르는 시나리오로 작성되며, 테스트 케이스를 이해하기 쉽고 읽기 쉽도록 설계됩니다.

 

Mockito는 Java 기반의 테스트 라이브러리로, Mock 객체를 생성하고 조작하는 기능을 제공합니다. Mockito를 사용하면 Mock 객체의 동작을 지정하고 검증할 수 있습니다.

 

BDDMockito는 Mockito가 확장된 것으로, given-when-then 구조를 따르는 BDD(Behavior Driven Development) 스타일의 테스트를 작성할 때 도움을 줍니다. given 영역에서 객체의 동작을 지정하고, when 영역에서 특정 상황을 시뮬레이션하고, then 영역에서 예상한 동작을 검증할 수 있습니다. 이를 통해 가독성이 좋고 이해하기 쉬운 테스트 코드를 작성할 수 있습니다.

 

 

1. Mockito를 이용한 테스트 코드

@Test
    @DisplayName("게시글 전체 조회가 가능하며 200을 반환한다.")
    void getArticles() throws Exception {
        // given
        Mockito.when(articleService.getArticles()).thenReturn(articleResponses);

        // when
        ResultActions result = mockMvc.perform(get("/api/v1/articles"));

        // then
        result.andExpectAll(
                status().isOk(),
                jsonPath("$.articleResponses.size()").value(2),
                jsonPath("$.articleResponses[0].id").value(2L),
                jsonPath("$.articleResponses[1].id").value(1L)
        );
    }

given 영역에 given이 아닌 when이 들어가게 되면서 이질적인 느낌이 듭니다.

 

2. BDDMockito로 변경한 테스트 코드

@Test
    @DisplayName("게시글 전체 조회가 가능하며 200을 반환한다.")
    void getArticles() throws Exception {
        // given
        BDDMockito.given(articleService.getArticles()).willReturn(articleResponses);

        // when
        ResultActions result = mockMvc.perform(get("/api/v1/articles"));

        // then
        result.andExpectAll(
                status().isOk(),
                jsonPath("$.articleResponses.size()").value(2),
                jsonPath("$.articleResponses[0].id").value(2L),
                jsonPath("$.articleResponses[1].id").value(1L)
        );
    }

given 영역에 given 메서드를 이용하게 되면서 given when then 시나리오에 맞게 쉽게 읽을 수 있게 됩니다.