๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

WINK-(Web & App)/Spring Boot ์Šคํ„ฐ๋””

[Spring Boot ์Šคํ„ฐ๋””] ํ•œ์ค€๊ต #2 ์ฃผ์ฐจ - ์„น์…˜3

๋ฐ˜์‘ํ˜•

๐Ÿƒ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ ์ •๋ฆฌ

๊ฐ•์˜ ๋ชฉํ‘œ๊ฐ€ ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์Šคํ”„๋ง์˜ ์ „๋ฐ˜์ ์ธ ํ๋ฆ„์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—!

 

→ ํšŒ์›ID ์™€ ์ด๋ฆ„ ๋งŒ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•œ๋‹ค!

 

→ ๊ธฐ๋Šฅ์€ ํšŒ์› ๋“ฑ๋ก๊ณผ ์กฐํšŒ!!

 

→ ๊ฐ€์ƒ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์•„์ง ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ(DB) ๊ฐ€ ์„ ์ •๋˜์ง€ ์•Š์Œ!! (๊ธฐ๋Šฅ์„ ํŒŒ์•…ํ•˜๊ณ  DB๋ฅผ ์„ ์ •ํ•ด๋ณด์ž..)

 

์ผ๋ฐ˜์ ์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต ๊ตฌ์กฐ๋Š”

→ ์ปจํŠธ๋กค๋Ÿฌ : ์›น MVC์˜ ์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• 

 

→ ์„œ๋น„์Šค : ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„

ex. ์ค‘๋ณต ๊ฐ€์ž…์ด ์•ˆ๋˜๋Š” ๋กœ์ง ๋“ฑ๋“ฑ ๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ณ„์ธต์ด๋‹ค.

 

→ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผ, ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ DB์— ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌ

 

→ ๋„๋ฉ”์ธ : ๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ ๊ฐ์ฒด

ex. ํšŒ์›, ์ฃผ๋ฌธ, ์ฟ ํฐ ๋“ฑ๋“ฑ ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌ๋จ

 

ํด๋ž˜์Šค ์˜์กด๊ด€๊ณ„๋Š”

 

์•„์ง ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๊ฐ€ ์„ ์ •๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค์ด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„ ์€ Memory ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

(์ผ๋‹จ ๊ฐœ๋ฐœ์€ ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋‹จ์ˆœํ•˜๊ฒŒ Memory ์— ๋„ฃ์—ˆ๋‹ค ๋บ๋‹ค ํ•˜๋Š” ๊ทธ๋Ÿฐ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉ → ๋‚˜์ค‘์— RDB, NoSQL ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์ €์žฅ์†Œ๋กœ ๋ฐ”๊ฟ€ ํ•„์š”์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ interface ๋กœ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•จ!)

 

๐Ÿƒ ํšŒ์› ๋„๋ฉ”์ธ๊ณผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

์šฐ์„  ํšŒ์› ๋„๋ฉ”์ธ์„ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ ์œ„ํ•ด domain package ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ๊ทธ ์•ˆ์— Member.java ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค!

package hello.hellospring.domain;

public class Member {
    private Long id; // ๊ณ ๊ฐ์ด ์ •ํ•˜๋Š” id ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ตฌ๋ถ„์„ ์œ„ํ•ด ์‹œ์Šคํ…œ์ด ์ •ํ•˜๋Š” id์ž„!!
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

alt + insert ๋กœ getter setter ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์‹œ๊ณ ~~

 

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์—ˆ์œผ๋ฉด!!! ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์‚ฌ์šฉ์„ ์œ„ํ•ด repository package ๋ฅผ ๋งŒ๋“ค์–ด์ค€ ํ›„์—

 

MemberRepository ๋ผ๋Š” interface ๋ฅผ ์ƒ์„ฑ! (interface ์ž„!!!)

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.List;
import java.util.Optional;

public interface MemberRepository {
    Member save(Member member);
    Optional<Member> findById(Long id);
    // Optional ์€ find~ ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ€์ ธ์™”์„ ๋•Œ NULL ์ธ ๊ฒฝ์šฐ NULL ์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ Optional ๋กœ ๊ฐ์‹ธ์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ญํ• ์ž„!
    Optional<Member> findByName(String name);

    List<Member> findAll();
}

์ด์–ด์„œ MemoryMemberRepository.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ค€๋‹ค!

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemberRepository {

    private static Map<Long, Member> store = new HashMap<>(); // key ๊ฐ€ ํšŒ์›์˜ id ์ด๋ฏ€๋กœ Long ์œผ๋กœ ํ•ด์คŒ!
    private static long sequence = 0L; // sequence ๋Š” 0, 1, 2 ์ฒ˜๋Ÿผ ํ‚ค๊ฐ’์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์• ์ž„

    @Override
    public Member save(Member member) {
        member.setId(++sequence); //store ์— put ํ•˜๊ธฐ์ „์— sequence ๋ฅผ ํ•˜๋‚˜ ์˜ฌ๋ ค์คŒ
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id)); // NULL ์„ Optional ๋กœ ๊ฐ์‹ธ์„œ ๋ฐ˜ํ™˜ํ•ด์คŒ
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny(); // ๊ฒฐ๊ณผ๊ฐ€ Optional ๋กœ ๋ฐ˜ํ™˜๋จ

        // loop ๋ฅผ ๋‹ค ๋Œ๋ฉด์„œ Map ์—์„œ ํ•˜๋‚˜๋ผ๋„ ์ฐพ์•„์ง€๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜ -> ๋งŒ์•ฝ ์—†๋‹ค๋ฉด Optional ์— NULL์ด ํฌํ•จ์ด ๋˜์„œ ๋ฐ˜ํ™˜๋จ
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }
}

alt + enter ๋กœ implementes methods ๋ฅผ ํ•ด์ค€๋‹ค.

 

๐Ÿƒ ํšŒ์› ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ

๊ทธ๋Ÿผ ์ด์ œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค~

 

test ํด๋” ์•„๋ž˜์— repository package ๋ฅผ ๋งŒ๋“ค์–ด ์ค€ ๋‹ค์Œ์— MemoryMemberRepositoryTest.java ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค!!

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

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

class MemoryMemberRepositoryTest { //๋‹ค๋ฅธ๋ฐ์„œ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ธ๊ฒŒ ์•„๋‹ˆ๋ฏ€๋กœ public ์œผ๋กœ ํ•  ํ•„์š”๋Š” ์—†์Œ!
    MemoryMemberRepository repository = new MemoryMemberRepository();

    @Test // Test ํ•  ๋กœ์ง!!
    public void save() {
        Member member = new Member();
        member.setName("spring");

        repository.save(member);

        Member result = repository.findById(member.getId()).get();
        System.out.println("result = " + (result == member));
        assertThat(member).isEqualTo(result);

        // System.out ์„ ์‚ฌ์šฉํ•ด์„œ ์ง์ ‘ ์ถœ๋ ฅ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์ง€๋งŒ
        // assert ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ถœ๋ ฅํ•˜์ง€ ์•Š๊ณ ๋„ ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ!!
    }

    @Test
    public void findByName() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);

        Member result = repository.findByName("spring1").get();

        assertThat(result).isEqualTo(member1);
    }

    @Test
    public void findAll() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member1.setName("spring2");
        repository.save(member2);

        List<Member> result = repository.findAll();

        assertThat(result.size()).isEqualTo(2);
    }

}

์ด์ œ Test ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด ~~ ์™„์ „ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์™œ๋ƒ๋ฉด Test ๋Š” ์ž‘์„ฑํ•œ ์ˆœ์„œ๋Œ€๋กœ๊ฐ€ ์•„๋‹ˆ๋ผ ์ž„์˜๋กœ ์„ ํƒ๋˜์–ด์„œ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—

 

์„œ๋กœ์˜ ์ˆœ์„œ(์˜์กด๊ด€๊ณ„ )์— ์ƒ๊ด€์—†์ด ์„ค๊ณ„๋˜์–ด์•ผ ํ•จ!

→ ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ๋๋‚  ๋•Œ ๋งˆ๋‹ค ๊ณต์šฉ ๋ฐ์ดํ„ฐ(์ €์žฅ์†Œ) ๋ฅผ ์ง€์›Œ์ค˜์•ผ ๋ฌธ์ œ๊ฐ€ ์—†์Œ!!

 

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ ~

 

MemoryMemberRepository ์— ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ !!

...

public void clearStore() {
        store.clear(); // store ์„ ์‹น ๋น„์›Œ์คŒ!!

MemoryMemberRepositoryTest.java ํŒŒ์ผ์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค!!

    @AfterEach // Test ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋๋‚ผ ๋•Œ๋งˆ๋‹ค ์–ด๋–ค ๋™์ž‘์„ ํ•˜๋Š” ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ์ด๋‹ค!!
    public void afterEach() {
        repository.clearStore(); // Test ๊ฐ€ ์ˆ˜ํ–‰๋˜๊ณ  ๋๋‚ผ ๋•Œ ๋งˆ๋‹ค repository ๋ฅผ ์‹น ์ง€์›€
    }

๋Œ€์„ฑ๊ณต..!!

 

๋”๋ณด๊ธฐ

๐Ÿ’ก TDD (ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ) : ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ๋งŒ๋“ค์–ด์„œ ํ‹€์„ ์žก๋Š” ๊ฐœ๋ฐœ ๋ฐฉ์‹!

 

๐Ÿƒ ํšŒ์› ์„œ๋น„์Šค ๊ฐœ๋ฐœ

ํšŒ์›๊ฐ€์ž… ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•ด๋ณผ๊ฑด๋ฐ!

๊ฐ™์€ ์ด๋ฆ„์˜ ํšŒ์›์€ ๋“ฑ๋กํ•  ์ˆ˜ ์—†๋Š” ๋กœ์ง์œผ๋กœ ์ž‘์„ฑํ•ด๋ณด์ž!!!

 

main ํด๋” ์•ˆ์— service ๋ผ๋Š” package๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ !

MemberService.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค!

package hello.hellospring.service;

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

import java.util.List;
import java.util.Optional;

public class MemberService {

    private final MemberRepository memberRepository = new MemoryMemberRepository();

    // ํšŒ์›๊ฐ€์ž…
    public Long join(Member member) {
        // ๊ฐ™์€ ์ด๋ฆ„์ด ์žˆ๋Š” ์ค‘๋ณต ํšŒ์› X

        validateDuplicateMember(member); //์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ
        memberRepository.save(member);
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName()) // Optional<Member> ๋กœ ๋ฐ˜ํ™˜๋จ
            .ifPresent(m -> { //Optional ๋กœ ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ  ifPresent ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. <-> ๊ธฐ์กด์ด์—ˆ์œผ๋ฉด if == null ์„ ์‚ฌ์šฉ
                throw  new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
            });
    }

    // ์ „์ฒด ํšŒ์› ์กฐํšŒ
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    // id๋กœ ํšŒ์› ์กฐํšŒ
    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ ๋กœ์ง์€

ctrl + alt + m ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค!!

 

์ „์ฒด ํšŒ์› ์กฐํšŒ์™€ id ํšŒ์› ์กฐํšŒ๋Š” ์ด๋ฏธ ๋งŒ๋“ค์–ด ๋†“์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ!!

 

๊ทธ๋Ÿผ ๋.

๐Ÿƒ ํšŒ์› ์„œ๋น„์Šค ํ…Œ์ŠคํŠธ

๊ทธ๋Ÿผ ์ด์ œ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ด์•ผ๊ฒ ์ฃ ~?

 

ctrl + shift + t ๋‹จ์ถ•ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋น ๋ฅด๊ฒŒ Test ๋ฅผ ์œ„ํ•œ ์ค€๋น„์ž‘์—…์„ ํ•˜๊ณ !!

 

 

์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ ํ‹€์ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค!!

 

ํ…Œ์ŠคํŠธ๋ฅผ ์ฒ˜์Œ ์ ‘ํ•  ๋•Œ์—๋Š”

 

given(์ƒํ™ฉ์ด ์ฃผ์–ด์ง€๊ณ ),

when(์ด๋Ÿฐ ์กฐ๊ฑด์—์„œ),

then(์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์•ผ ํ•จ)

 

์ฃผ์„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉด ๊ต‰์žฅํžˆ ๋„์›€์ด ๋จ!

 

๋”๋ณด๊ธฐ

๐Ÿ’ก test ๋Š” ์‹ค์ œ ์ฝ”๋“œ์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ณผ๊ฐํ•˜๊ฒŒ ํ•œ๊ธ€์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง๊ด€์ ์œผ๋กœ ์‹คํ–‰ํ•˜์—ฌ๋„ ์ข‹์Œ!!

 

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Optional;

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

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("spring");

        //when (์ด๋Ÿด ๋•Œ์—)
        Long saveId = memberService.join(member);

        //then (์ด๊ฒŒ ๋‚˜์™€์•ผ ํ•จ)
        Member findeMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findeMember.getName());
    }

    @Test
    public void ์ค‘๋ณต_ํšŒ์›_์˜ˆ์™ธ() {
        // member 2 ๋ช…์˜ ์ด๋ฆ„์ด ๋˜‘๊ฐ™๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ด์•ผํ•จ!! -> ์ด๊ฑธ ํ™•์ธ!

        //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));
        // assertThrow ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ๋ฐœ์ƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ์˜ˆ์™ธ๋ฅผ ๊ฒ€์ฆ
        Assertions.assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");

        /*
        memberService.join(member1);
        try {
            memberService.join(member2);
            fail(); // ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด fail ์ž„!!
        } catch (IllegalStateException e) {
            Assertions.assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์›์ž…๋‹ˆ๋‹ค.");
        }
        */

        //then
    }
}

์ตœ์ข… test ์ฝ”๋“œ๋Š” ์ด๋ ‡๊ฒŒ ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค!

 

์ฃผ์„ ์ฒ˜๋ฆฌ๋œ try catch ๋ฌธ์œผ๋กœ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ

assertThat ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๊ฐ„ํŽธํ•˜๋‹ค!

 

๋˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด @BeforeEach ๋Š” ๋ญ์ง€..? ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ

 

MemberService ์™€ MemberServiceTest ์˜ MemoryMemberRepository ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋ฏ€๋กœ

๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์“ฐ๊ฒŒ ์„ค์ •ํ•ด์ฃผ๋Š”๊ฒŒ ์ข‹์Œ!

 

๋”ฐ๋ผ์„œ @AfterEach ์™€ ๋ฐ˜๋Œ€๋กœ Test ๊ฐ€ ์ง„ํ–‰๋˜๊ธฐ ์ „์— Repository ๋ฅผ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋จ!

 

๊ธฐ์กด์˜ MemberService.java ์—์„œ new ๋ฅผ ์ด์šฉํ•˜์—ฌ memberRepository ๋ฅผ ์‚ฌ์šฉํ•˜๋˜ ๋ถ€๋ถ„๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊ฟ”์ค€๋‹ค!

...

private final MemberRepository memberRepository;
    
    // ์™ธ๋ถ€์—์„œ Repository๋ฅผ ๋„ฃ์–ด์คŒ
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

...

→ ์ด์ œ Test์™€ ๊ธฐ์กด ํŒŒ์ผ์ด ์„œ๋กœ ๊ฐ™์€ MemoryRepository ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ!

 

๋ฐ˜์‘ํ˜•