Service ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ๋‹จ์ˆœํžˆ ์„œ๋น„์Šค ๋กœ์ง์ด ๋Œ์•„๊ฐ€๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๋ชจ๋“  ๊ณ„์ธต๊ณผ ๊ด€๊ณ„๋ฅผ ๋Š๊ณ , ์˜ค๋กœ์ง€ ๋กœ์ง๋งŒ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๊ทธ๋ ‡๊ธฐ์—, mock ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , stubbing ๊ณผ์ •์„ ํ†ตํ•ด ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์ž˜ ์ฐพ์•„๋ณด๋ฉด when().thenReturn() ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•˜๊ณ , given().willReturn() ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

๋‘˜ ๊ฐ„์˜ ์ฐจ์ด๋ฅผ ์•Œ์•„๋ณด์ž.

1. Mock


Mock์ด๋ž€ ๋ชจ๋“ˆ์˜ ๊ฒ‰๋ชจ์–‘์ด ์‹ค์ œ ๋ชจ๋“ˆ๊ณผ ๋น„์Šทํ•˜๋„๋ก ๋งŒ๋“  ๊ฐ€์งœ ๊ฐ์ฒด์ด๋‹ค.

์œ„์— ์ƒ์ˆ ํ•œ๋Œ€๋กœ, Service ๊ณ„์ธต์—์„œ ์˜์กด์„ฑ์„ ์ œ๊ฑฐํ•œ ์ƒํƒœ๋กœ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์–ด๋ ค์›Œ ์˜์กด์„ฑ์„ ๋‹จ์ ˆ์‹œํ‚ค๋Š”๋ฐ ๋„์›€์„ ์ฃผ๋Š” ๊ฐ์ฒด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.


2. Mockito


Mock ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ Framework ์ค‘์— ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ Mockito์ด๋‹ค.

Mockito๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” @ExtendWith(MockitoExtention.class) ๋ฅผ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ์ƒ๋‹จ์— ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด @Mock ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ Mock ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์‹œ๋ฅผ ๋ณด์ž.

@ExtendWith(MockitoExtension.class)
class PostServiceTest {

    @Mock
    private PostRepository postRepository;

    @InjectMocks
    private PostService postService;

    private Post post;

    @BeforeEach
    void setup() {
        post = Post.builder().id(1).title("title").body("body").user(user).build();
    }

    @Test
    @DisplayName("ํฌ์ŠคํŠธ ์ƒ์„ธ ์กฐํšŒ ์„ฑ๊ณต")
    void findPost_success() throws Exception {
        when(postRepository.findById(post.getId())).thenReturn(Optional.of(post));

        PostDetailResponse postDetail = postService.findPost(1);
        assertThat(postDetail.getId()).isEqualTo(1);
        assertThat(postDetail.getTitle()).isEqualTo("title");
        assertThat(postDetail.getBody()).isEqualTo("body");
        assertThat(postDetail.getUserName()).isEqualTo("user");

        verify(postRepository, times(1)).findById(post.getId());
    }
}

์œ„ ์˜ˆ์‹œ๋Š” ํฌ์ŠคํŠธ ์ƒ์„ธ ์กฐํšŒ ์„ฑ๊ณต ํ…Œ์ŠคํŠธ ์ƒํ™ฉ์ด๋‹ค.

@Mock ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด mock PostRepository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ ,

@InjectMocks ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด @Mock ์ด ๋ถ™์€ ๋ชฉ๊ฐ์ฒด๋ฅผ @InjectMocks ์ด ๋ถ™์€ ๊ฐ์ฒด์— ์ฃผ์ž…ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ , when ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ๋™์ž‘์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ์–ด๋–ค ์ƒํ™ฉ์—์„œ Mock ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์ด๋‹ค.

์ด๊ฒƒ์„ Stubbing ์ด๋ผ๊ณ  ํ•œ๋‹ค.

assertThat์„ ํ†ตํ•ด ์‹ค์ œ๊ฐ’๊ณผ ์˜ˆ์ธก๊ฐ’์„ ๊ฒ€์ฆํ•˜๊ณ , ๋งˆ์ง€๋ง‰์œผ๋กœ verify ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด mock ๊ฐ์ฒด์— ๋‚ด๊ฐ€ ๋™์ž‘์„ ์ง€์ •ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋๋Š”์ง€ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ BDDMockito์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.


3. BDDMockito


BDD ๋ž€ Behavior-Driven Development์˜ ์•ฝ์–ด๋กœ, ๋ฌด์—‡์„ ํ…Œ์ŠคํŠธํ•  ๊ฒƒ์ธ๊ฐ€ ์— ์ดˆ์ ์ด ๋งž์ถฐ์ ธ ์žˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ตœ์šฐ์„ ์œผ๋กœ ํ•˜๊ธฐ์— Given(์กฐ๊ฑด), When(๊ธฐ๋Šฅ ์ˆ˜ํ–‰), Then(์˜ˆ์ƒ ๊ฒฐ๊ณผ) ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค ํŒจํ„ด์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด, ์œ„์˜ ์ฝ”๋“œ์—์„œ ์–ด์ƒ‰ํ•œ ๋ถ€๋ถ„์„ ๋ฐ”๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

๋ฐ”๋กœ, Stubbing ํ•˜๋Š” ๋ถ€๋ถ„์ด ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค.

when(postRepository.findById(post.getId())).thenReturn(Optional.of(post));

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํ๋ฆ„ ์ƒ, when().thenReturn() ๋ถ€๋ถ„์€ ํ…Œ์ŠคํŠธ ์‹œ์ž‘ ์ง€์ ์ธ ์กฐ๊ฑด์„ ๊ฑฐ๋Š” ์ƒํ™ฉ์ด๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค ํŒจํ„ด ์ƒ Given ์ง€์ ์ด๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, when์œผ๋กœ ์‹œ์ž‘ํ•˜๋‹ˆ ๋ถ„๋ช…ํžˆ ์–ด์ƒ‰ํ•˜๋‹ค.

์ด๋Ÿฐ ๋ถ€๋ถ„์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋งž๊ฒŒ๋” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํ๋ฆ„์ด ์ด์–ด์งˆ ์ˆ˜ ์žˆ๊ฒŒ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์ค€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋ฐ”๋กœ BDDMockito๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์‚ฌ์‹ค BDDMockito ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๋ณ„๋„์˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•„๋‹ˆ๋ผ Mockito๋ฅผ ์ƒ์†ํ•œ ํด๋ž˜์Šค์ด๋‹ค.

์„ธ๋ถ€ ๋™์ž‘์—๋Š” ์ฐจ์ด๊ฐ€ ์—†๊ณ , ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

์œ„์˜ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

@ExtendWith(MockitoExtension.class)
class PostServiceTest {

    @Mock
    private PostRepository postRepository;

    @InjectMocks
    private PostService postService;

    private Post post;

    @BeforeEach
    void setup() {
        post = Post.builder().id(1).title("title").body("body").user(user).build();
    }

    @Test
    @DisplayName("ํฌ์ŠคํŠธ ์ƒ์„ธ ์กฐํšŒ ์„ฑ๊ณต")
    void findPost_success() throws Exception {
        given(postRepository.findById(post.getId())).willReturn(Optional.of(post));

        PostDetailResponse postDetail = postService.findPost(1);
        assertThat(postDetail.getId()).isEqualTo(1);
        assertThat(postDetail.getTitle()).isEqualTo("title");
        assertThat(postDetail.getBody()).isEqualTo("body");
        assertThat(postDetail.getUserName()).isEqualTo("user");

        verify(postRepository, times(1)).findById(post.getId());
    }
}

References

Tags:

Categories:

Date:

Leave a comment