MapleStory Cookie With Halo

๐Ÿƒ Spring/๐Ÿƒ Spring Boot

[SpringBoot][JUnit]ํšŒ์›๊ด€๋ฆฌ-์„œ๋น„์Šค์™€ ํ…Œ์ŠคํŠธ

๋‰ด์ด NUEY 2025. 1. 5. 03:17
๋ฐ˜์‘ํ˜•

 

์ด์ „ ํŽธ : 2025.01.04 - [๐Ÿƒ Spring/๐Ÿƒ Spring Boot] - [SpringBoot]ํšŒ์›๊ด€๋ฆฌ-๋„๋ฉ”์ธ๊ณผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ

 


 

@Service

 

  1. ํด๋” src-main-java-hello-hellspring์—์„œ serviceํŒจํ‚ค์ง€์˜ MemberService ํด๋ž˜์Šค.
  2. ํด๋ž˜์Šค ์œ„์— @Service๋ฅผ ์ ์–ด์ค€๋‹ค.
  3. ์„œ๋น„์Šค ์ฝ”๋”ฉ
    • ์ฝ”๋“œ
      ์•„๋ž˜ ์ „์ฒด์ฝ”๋“œ๋Š” ํฌ์ŠคํŠธ์˜ ๋‚ด์šฉ์„ ๋ชจ๋‘ ๋ฐ˜์˜ํ•œ ์ฝ”๋“œ๋กœ ์ด ์บก์ฒ˜๋ณธ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
    • ์ „์ฒด์ฝ”๋“œ
      ๋”๋ณด๊ธฐ
      package hello.hellospring.service;
      
      import java.util.List;
      import java.util.Optional;
      
      import org.springframework.stereotype.Service;
      
      import hello.hellospring.domain.Member;
      import hello.hellospring.repository.MemberRepository;
      
      @Service
      public class MemberService {
      
          private final MemberRepository memberRepository;
      
          public MemberService(MemberRepository memberRepository) {
              this.memberRepository = memberRepository;
          }
      
          /**
           * ํšŒ์› ๊ฐ€์ž…
           * @param member
           * @return ํšŒ์›id
           */
          public Long join(Member member) {
              validateDuplicateMember(member); // ์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ
              memberRepository.save(member);
              return member.getId();
          }
      
          private void validateDuplicateMember(Member member) {
              memberRepository.findByName(member.getName())
                      .ifPresent(m -> {
                          throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
                      });
          }
      
          /**
           * ์ „์ฒด ํšŒ์› ์กฐํšŒ
           * @return ์ „์ฒดํ˜ธ์›๋ฆฌ์ŠคํŠธ
           */
          public List<Member> findMembers() {
              return memberRepository.findAll();
          }
      
          public Optional<Member> findOne(Long memberId) {
              return memberRepository.findById(memberId);
          }
      
      }
    • private final MemberRepository memberRepository = new MemoryMemberRepository();
      • private final
        → ํด๋ž˜์Šค์—์„œ๋งŒ ์ƒ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”

      • MemberRepository memberRepository = new MemoryMemberRepository();
        → ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํƒ€์ž…์œผ๋กœ ํ•˜๋Š” ๊ตฌํ˜„ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    • Optional ์„ค๋ช…
      memberRepository.findByName(member.getName())
                      .ifPresent(m -> {
                          throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
                      });

      • memberRepository.findByName(member.getName()) : ๋ฉค๋ฒ„์ด๋ฆ„์„ ์ฐพ์•„ Optional์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 

      • ๋”ฐ๋ผ์„œ ๊ทธ ๋’ค์˜ ์ฝ”๋“œ๋“ค์€ ๋ชจ๋‘ Optional์˜ ๋ฉ”์„œ๋“œ๋“ค ์ž…๋‹ˆ๋‹ค.

      • Optional์˜ isPresent()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๊ฐ’์ด ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ต๋‹ˆ๋‹ค.

      • ..ifPresent(m -> { throw... : Optional์— ํšŒ์›์ด ์žˆ์—ˆ์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  4. ๋‚˜๋จธ์ง€๋Š” Rrepository์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค๋ช…์„ ์ƒ๋žตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 


 

โ€ป ์„œ๋น„์Šค์˜ ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜๋ช…์€ ๋น„์ง€๋‹ˆ์Šค์— ๊ฐ€๊น๊ฒŒ ์ด๋ฆ„์„ ์ง“๋Š”๋‹ค.

 


 

  • ๊ถŒ์žฅ ์ฝ”๋“œ ์ž‘์„ฑ๋ฒ•
    1. ์•„๋ž˜ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ Optional์„ ๋ณ€์ˆ˜๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.
    2. Optional์˜ isPresent()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๊ฐ’์ด ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ต๋‹ˆ๋‹ค. 
    3. ์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ 

 

Test

 

ํ…Œ์ŠคํŠธ์˜ ๊ตฌ์กฐ์™€ ์‚ฌ์šฉ๋ฒ•์€ ์ด์ „ํŽธ์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

2025.01.04 - [๐Ÿƒ Spring/๐Ÿƒ Spring Boot] - [SpringBoot]ํšŒ์›๊ด€๋ฆฌ-๋„๋ฉ”์ธ๊ณผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ. & ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค

๊ทธ๋ฆฌ๊ณ  ์ด๋ฒˆ ํฌ์ŠคํŠธ๋Š” ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

2025.01.05 - [๐Ÿ›  ๋„๊ตฌ/โžฐ Visual Studio Code] - [VScode]ํ…Œ์ŠคํŠธ ์ž๋™์ƒ์„ฑ source action

 


 

given / when / then

 

 

  • given : ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ 

  • when : ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๊ณ 

  • then : ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋˜์—ˆ๋Š” ์ง€ ํ™•์ธํ•˜๋Š” ์ˆœ์„œ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

 

์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œํ‚ค๊ธฐ

 

  1. ์ค‘๋ณตํšŒ์›์„ ๊ฒ€์ฆํ•˜๋Š” validateDuplicateMember๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ ค ํ•œ๋‹ค.
  2. ์ค‘๋ณต ํ…Œ์ŠคํŠธ ์ฝ”๋“œ
    • ์ฝ”๋“œ
    • ๋ฉค๋ฒ„ ๋„๋ฉ”์ธ์„ ์ค‘๋ณต๋œ ์ด๋ฆ„์œผ๋กœ ๋‘๊ฐœ ๋งŒ๋“ค์—ˆ๋‹ค.

    • ์ค‘๋ณต ๊ฐ€์ž…์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

    • ์ด ๋•Œ ์˜ค๋ฅ˜๋ฅผ try/catch๋ฌธ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

    • catch๋ถ€๋ถ„์ด  ์กฐ๊ธˆ ํฅ๋ฏธ๋กญ๋‹ค.
      } catch (IllegalStateException e) {
                  assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.12341234");
              }

      • catch๋กœ ์ด๋ฏธ ์žก์€ ์—๋Ÿฌ๋ฅผ assertThat์„ ํ†ตํ•ด ๋˜ ํ•œ๋ฒˆ ๊ฒ€์ฆํ•˜๊ณ  ์žˆ๋‹ค.

      • ๋ฐ˜ํ™˜๋œ ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๊ฐ€ ์˜ˆ์ƒํ•œ ๋ฉ”์‹œ์ง€์™€ ๋™์ผํ•œ ์ง€ ํ™•์ธํ•˜์—ฌ

      • ๋‹ค๋ฅด๋‹ค๋ฉด ํ…Œ์ŠคํŠธ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

 

Assertions.assertThrows(์˜ˆ์ƒ ์˜ˆ์™ธํด๋ž˜์Šค, ์‹คํ–‰์ฝ”๋“œLambda)
: try/catch ๋Œ€์‹  ๊ฐ„๋‹จํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ฐธ๊ณ ๋กœ org.junit.jupiter.api.AssertionsํŒจํ‚ค์ง€์˜ ๋ฉ”์„œ๋“œ์ด๋‹ค.

 

  1. ์„œ๋น„์Šค ๊ฐ€์ž…๋ฉ”์„œ๋“œ์—์„œ ์ค‘๋ณต๋œ ์ด๋ฆ„์ด ๊ฐ€์ž…์„ ์‹œ๋„ํ•˜๋ฉด IllegalStateException๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

  2. assertThrows๋Š” ์˜ˆ์ƒ๋œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด TEST RESULT๊ฐ€ โœ…ํ†ต๊ณผํ•œ๋‹ค.

 

โ€ป ์ด์™€ ๊ฐ™์ด ์˜ˆ์™ธ ์ž์ฒด๋ฅผ ๋ณ€์ˆ˜๋กœ ๋งŒ๋“ค์–ด ๊ฒ€์ฆํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 


 

service์™€ test์—์„œ ์‚ฌ์šฉํ•˜๋Š”
repository๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ๊ธฐ

 

  1. ์‹ค์ œ ์ฝ”๋“œ์™€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ๋™์ผํ•œ Repository๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ๋ฐ”๊ฟ”๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  2. ์ด์ „ ์ฝ”๋“œ
  3. ์ˆ˜์ • ์ฝ”๋“œ
    • ๋‹ค๋ฅธ ํด๋ž˜์Šค ์„œ๋น„์Šค ํ˜ธ์ถœ ์‹œ, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ๋” ํ•ฉ๋‹ˆ๋‹ค.
      private final MemberRepository memberRepository;
      
          public MemberService(MemberRepository memberRepository) {
              this.memberRepository = memberRepository;
          }
       
    • ํ…Œ์ŠคํŠธํด๋ž˜์Šค
      public class MemberServiceTest {
      	// 1.
          MemberService memberService;
          MemoryMemberRepository memberRepository;
      
          @BeforeEach
          public void BeforeEach() {
              memberRepository = new MemoryMemberRepository();
              // 2.
              memberService = new MemberService(memberRepository);
          }

      1. ํ…Œ์ŠคํŠธ์—์„œ๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„œ๋น„์Šค์™€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ 

      2. @BoforeEash ๋ฉ”์„œ๋“œ ์•ˆ์— ์„œ๋น„์Šค ์ธ์Šคํ„ด์Šค ๋งŒ๋“ค ๋•Œ (์ „์—ญ๋ณ€์ˆ˜ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ)๋ฅผ ๋‹ด์•„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

      3. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋น„์Šค์™€ ํ…Œ์ŠคํŠธ๋Š” ๊ฐ™์€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐ŸŒŸ ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์„ DI (Dependency injection). ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

↓ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ „์ฒด์ฝ”๋“œ (findMembers()์™€ findOne() ํ•จ์ˆ˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์ œ๊ฐ€ ์ž‘์„ฑํ•ด ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค.)

๋”๋ณด๊ธฐ
package hello.hellospring.service;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;

public class MemberServiceTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void BeforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void AfterEach() {
        memberRepository.clearStore();
    }

    @Test
    void ํšŒ์›๊ฐ€์ž…() {
        //given
        Member member = new Member();
        member.setName("pring");

        //when
        Long saveId = memberService.join(member);

        //then
        Member findMember = memberService.findOne(saveId).get();
        assertThat(member.getName()).isEqualTo(findMember.getName());
    }

    @Test
    public void ์ค‘๋ณต_ํšŒ์›_์˜ˆ์™ธ() {
        //given
        Member member1 = new Member();
        member1.setName("spring");

        Member member2 = new Member();
        member2.setName("spring");

        //when : ์ผ๋ถ€๋Ÿฌ ์ค‘๋ณต๊ฐ€์ž…์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
        memberService.join(member1);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        
        assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
        
/*
        try {
            memberService.join(member2);    
            fail();
        } catch (IllegalStateException e) {
            assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.12341234");
        }
*/
        //then
    }

    @Test
    void findMembers() {
        //given
        Member member1 = new Member();
        member1.setName("Spring1");
        memberService.join(member1);

        Member member2 = new Member();
        member2.setName("Spring2");
        memberService.join(member2);

        List<Member> lst = new ArrayList<>(Arrays.asList(member1));
        lst.addAll(Arrays.asList(member2));

        //when
        List<Member> result = memberService.findMembers();
        
        //then
        for (int i = 0; i < result.size(); i++) {
            assertThat(result.get(i)).isEqualTo(lst.get(i));
        }
    }

    @Test
    void findOne() {
        // given
        Member member1 = new Member();
        member1.setName("Spring1");
        memberService.join(member1);

        Member member2 = new Member();
        member2.setName("Spring2");
        memberService.join(member2);

        //when then
        memberService.findOne(member2.getId())
            .ifPresent(m -> {
                assertThat(m).isEqualTo(member2);
            });
    }

}

 


 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์‚ฌ์‹ค ํ•œ๊ธ€๋กœ ์ ์–ด๋„ ์ƒ๊ด€์ด ์—†๋‹ค.
๐ŸŒŸ  ๋นŒ๋“œ ๋  ๋•Œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ํฌํ•จ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 


โ€ป ์ฐธ์กฐ : https://www.inflearn.com/roadmaps/373

๋ฐ˜์‘ํ˜•