💡 개발한 기능을 실행해서 테스트 하는 기존 방법들
- 개발한 기능을 실행해서 테스트 할 때 자바의 main 메서드를 통해서 실행하거나
 - 웹 애플리케이션의 컨트롤러를 통해 해당 기능을 실행함
 위의 방법은 준비하고 실행하는데 오래 걸리고, 반복 실행하기 어려우며, 여러 테스트를 한 번에 실행하기 어렵다는 단점이 있다.
이 문제를 해결하기 위해 JUnit 프레임워크로 이러한 문제를 해결한다.
/* save test */
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
class MemoryMemberRepositoryTest {
    MemoryMemberRepository repository = new MemoryMemberRepository();
    @Test // 테스트 실행시 반드시 필요
    public void save(){
        Member member = new Member();
        member.setName("spring");
        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        // 반환 타입이 Optional 이므로, get()을 통해 값을 꺼낼 수 있음
        
        /* member와 result가 같은지 확인하는 방법들 */
        System.out.println("result=" + (result == member)); // result=true
       
    }
}
Assertions.assertEquals(member, null);
// result와 member가 같은지 확인할 수 있는 메서드
// org.junit.jupiter.api import
🔹 두 값이 같은 경우
- 출력된 것은 없지만 초록불이 들어옴
 🔹 두 값이 다른 경우
- 기대한값(Expected)와 실제값(Actual)과 함께 오류 발생
 
import static org.assertj.core.api.Assertions.*;
assertThat(member).isEqualTo(result);
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
class MemoryMemberRepositoryTest {
    
    MemoryMemberRepository repository = new MemoryMemberRepository();
    @Test
    public void save() {
        Member member = new Member();
        member.setName("spring");
        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        // 반환 타입이 Optional 이므로, get()을 통해 값을 꺼낼 수 있음
        // System.out.println("result=" + (result == member)); // result=true
        // Assertions.assertEquals(member, null);
        // result와 member가 같은지 확인할 수 있는 메서드
        assertThat(member).isEqualTo(result);
    }
    
    @Test
    public void findByName() {
        Member member1 = new Member();
        member1.setName("spring");
        repository.save(member1);
        Member member2 = new Member();
        member2.setName("spring1");
        repository.save(member2);
        Member result = repository.findByName("spring").get();
        assertThat(result).isEqualTo(member1);
    }
        
    @Test
    public void findAll(){
        Member member1 = new Member();
        member1.setName("spring2");
        repository.save(member1);
        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);
        List<Member> result = repository.findAll();
        assertThat(result.size()).isEqualTo(3);
	}
}
여기서 잠깐 🤚
전체 test를 할 때, 처음에는 안났던 findByName( ) 메서드에서 오류가 발생했다..!
💡 테스트 케이스 주의사항
- 모든 테스트는 순서가 보장이 안된다.
 - 메서드가 순서와 상관없이 따로 동작할 수 있도록 설계를 해야한다.
 - 테스트 케이스는 순서에 의존적으로 절대 설계하면 안되요!
 이를 해결하기 위해 테스트가 끝나면 저장소 혹은 공용 데이터를 clear 해주는 것이 좋다.
- MemotyMemberRepository에 테스트가 끝날 때마다 repository를 지워주는 코드가 필요하다.
 /* MemoryMemberRepository */ // 아래 메서드 추가 public void clearStore(){ store.clear(); }
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 static org.assertj.core.api.Assertions.*;
class MemoryMemberRepositoryTest {
    MemoryMemberRepository repository = new MemoryMemberRepository();
    @AfterEach 
    // 모든 메서드가 연산을 수행한 후 동작할 수 있도록 선언
    // 콜백 메서드
    public void afterEach() {
        repository.clearStore();
    }
    
    @Test
    public void save() {
        Member member = new Member();
        member.setName("spring");
        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        // 반환 타입이 Optional 이므로, get()을 통해 값을 꺼낼 수 있음
        // System.out.println("result=" + (result == member)); // result=true
        // Assertions.assertEquals(member, null);
        // result와 member가 같은지 확인할 수 있는 메서드
        assertThat(member).isEqualTo(result);
    }
        @Test
        public void findByName() {
            Member member1 = new Member();
            member1.setName("spring");
            repository.save(member1);
            Member member2 = new Member();
            member2.setName("spring1");
            repository.save(member2);
            Member result = repository.findByName("spring").get();
            assertThat(result).isEqualTo(member1);
        }
        @Test
        public void findAll(){
            Member member1 = new Member();
            member1.setName("spring2");
            repository.save(member1);
            Member member2 = new Member();
            member2.setName("spring2");
            repository.save(member2);
            List<Member> result = repository.findAll();
            assertThat(result.size()).isEqualTo(2);
        }
    }
💡 TDD ( Test Driven Development )
- 테스트 주도 개발을 지향해요!
 - 반복 테스트를 이용한 소프트웨어 방법론
 - 작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현
 - 테스트를 먼저 만들고 구현 클래스를 만들어서 돌려본 것
 🔸 Junit
- 전 세계적으로 가장 널리 사용되고 있는 'Java 단위 테스트 프레임워크'