1장의 UserDaoTest의 메인으로 작성한 테스트는 매번 직접 db의 정보를 삭제하고, 직접 결과를 비교하며 테스트를 진행해야 하는 단점이 있다
테스트 실패
프레임워크의 동작 원리는 IoC이기에 프레임워크에서 동작하는 코드는 main()메소드나 오브젝트 실행 코드도 필요 없다.→ main()의 테스트 코드를 일반 메소드로 옮기기
java.lang.Exception: No runnable methods(main에서 실행할 때만)
import org.junit.Test;(후) ⇒ main 메서드에서 테스트 실행 가능
import org.junit.jupiter.api.Test;(전) ⇒ 함수 단위로 테스트 실행 가능

assertThat(T actual, Matcher<? super T> matcher)
의 형태로 matcher로 is를 사용해 첫 번째 파라미터와 is 자신의 파라미터가 동일한지 비교하고 테스트 오류시 AssertionError 생성
db를 삭제하고 테스트를 실행하지 않으면 테스트 오류가 발생하는데 동일한 코드로 반복적으로 테스트 수행 시 테스트의 성공 여부가 달라지면 안된다
→ 테스트 수행 후 사용자 정보를 삭제하자(모종의 이유로 테스트 시작 전 users 테이블에 데이터가 들어가 있을 수 있음.
→ 테스트 전 users 테이블을 비우고 테스트 시작(이 방법 채택)
addAndGet() 테스트 보완
보완해라~
dao.get(user1.getId());가 없을 때→ 테스트 에러
1) null 리턴
2) id 해당 정보를 찾을 수 없다고 예외 던지기→ 에러 코드가 테스트를 통과하도록 설정!


@Test 어노테이션이 붙은 테스트 별로 통과됐음을 확인할 수 있다
포괄적 테스트를 만들자: 간단해보여도 다양한 상황과 입력값을 고려하는 테스트할 수 있는 포괄적인 테스트코드를 만들어둬야 특정한 상황에서의 오동작 확인 가능 + 네거티브 테스트(를 만들자!)
테스트의 조건, 행위, 결과를 사전에 문서의 형식으로 생성 후 코드를 생성하자
조건: 사용자 정보 존재 X/ 행위: 없는 id로 get/결과: 예외 던짐
⇒ 테스트코드를 설계 문서처럼 표현 가능
TDD: 만들고자 하는 기능을 담은 테스트 코드 생성→ 테스트 성공을 위한 코드 작성하는 방식
실패한 테스트를 성공시키기 위한 목적이 아닌 코드는 만들지 않는다!
TDD의 장점
테스트 작성의 작업 주기는 짧게!(테스트 조금 작성, 바로 코드 작성) 이 단계를 자주 반복할 것
public void 형 @Test 메소드 검색→ 테스트 메소드마다 클래스 오브젝트 생성→ @Before 실행→ 테스트 메소드 실행 후 결과 저장→ @After 실행→ 모든 테스트 완료 후 결과 반환
테스트 메소드마다 새로운 클래스 생성 → 각 테스트가 독립적으로 실행됨을 보장하기 위해
픽스처: 테스트 수행에 필요한 정보나 오브젝트
@Before 메소드마다 애플리케이션 컨텍스트가 세 번 만들어진다.→ 빈의 초기화와 생성에 리소스가 많이 사용된다
@Autowired: DI용 어노테이션으로 Autowired가 붙은 인스턴스 변수가 있으면, 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내 빈 검색 후 타입과 일치하는 빈 있으면 인스턴스 변수에 주입. & DI 설정 없이 필드의 타입 정보로 빈 가져오기 가능(타입에 의한 자동 와이어링)
@RunWith(SpringJunit4ClassRunner.class)(스프링 테스트 컨텍스트 프레임워크의 Junit 확장 기능 사용할거라 지정함): 어플리케이션 컨텍스트와는 다른 스프링 테스트 컨텍스트!!
@ContextConfiguration(테스트 컨텍스트 자동 생성될 애플리케이션 컨텍스트 위치 지정): 빈 정보 지정 위치 명시로 이 파일에서 빈을 검색해서 주입해준다.


Junit 확장 기능은 테스트 실행 전 한 번 AC 만들고, 테스트 오브젝트 생성 때 마다 컨텍스트를 주입하는데 스프링 AC는 초기화 시 자기 자신도 빈으로 등록함.
스프링 테스트 컨텍스트 프레임워크
Autowired는 타입을 가진 빈을 자동으로 찾는데 같은 타입의 빈이 두 개 이상 있으면 어떤 빈을 가져올지 정하지 못한다.→ 이럴 경우 변수의 이름과 같은 이름의 빈이 있는지 확인
빈을 등록한다는 것: 어떤 함수가 어떤 객체를 생성해서 반환하는지, 어떤 객체를 주입하는지 그 관계를 적어놓는다는 것

⇒ UserDao Setter 함수의 매개변수 이름인 dataSource에 빈 dataSource의 값(SimpleDriverDataSource)를 넣는다!
빈 등록→ 객체간의 관계에 대한 정보 등록(사전 같은 것)

UserDao라는 타입을 가진 빈을 검색→ id가 userDao인 빈
⇒ @Autowired 설정만 하면 알아서 AC 참고해서 db 연결까지 해준다!
this.dao = this.context.getBean("userDao", UserDao.class);
이러한 DL 작업을 대신 해주는 것이 스프링 컨테이너이다 = 이런 작업을 코드 내에서 DaoFactory 해주고 있는데 이러한 IoC 작업을 해주는 것이 스프링 컨테이너 = DaoFactory가 없어도 빈만 등록됐으면 된다

XML파일 작성 후 @Autowired <=> (대체) @Bean 어노테이션으로 빈 등록, getBean으로 빈 검색해서 가져오는 단계
결론: 스프링 IoC= FactoryClass(우리가 쓰는 스프링부트 방식)
기존에는 의존성 주입 =new를 하지 않아도 객체 생성 이라고 생각을 했었는데
객체 생성에 필요한 프로퍼티를 스프링 컨테이너가 자동으로 주입해주는 IoC를 수행하는 것