1. Com.springsource.junit : junit
2. Commons-logging : Spring-context가 사용
3. Mysql-connector : Mysql JDBC
4. Spring-aop : 스프링 기능 자체의 aop
5. Spring-bean : 스프링 빈을 활용하는 경우 필요. 스프링의 XML 설정파일과 자바 애노테이션을 파싱 하는데 필요한 클래스 포함
6. Spring-context : 스프링 코어를 확장한 많은 클래스가 들어 있는데 모든 클래스는 EJB, JNDI(Java Naming Directory Interface), JMX용 클래스와 연동하는데 applicationcontext기능을 사용해야 하며 스프링 리모팅 클래스, 동적 스크립팅 언어(제이루비, 그루비등)와 연동하는 클래스, 빈 유효성검증(JSR-303) API, 스케줄링을 하는 클래스도 포함되어 있다.
7. Spring-core : 모든 스프링 모듈에서 필요한 모듈. 다른 스프링 모듈에서 사용하는 공통 클래스가 포함됨.
8. Spring-dao : EmpltyResultDataAccessException 등 사용을 위한 jar
9. Spring-expression : 스프링 표현언어(SpEL) 지원 클래스 포함.
10. Spring-jdbc : 스프링이 지원하는 jdbc.
11. Spring-test.jar
- @RunWith : Junit 프레임워크의 테스트 실행방법을 확장시 사용.
- SpringJUnit4ClassRunner : 어플리케이션컨텍스트를 만들고 관리하는 확장 클래스
- @ContextConfiguration(경로) : 자동으로 만들어줄 어플리케이션 컨텍스트 설정파일
이쯤에서 다시 한번 정리
*어플리케이션 컨텍스트 : 어플리케션 전반에 걸쳐 모든 구성요소를 제어 작업을 담당(객체 생성과 관리 및 인터셉트 전,후 처리 등)
21. @RunWith : 스프링 테스트 컨텍스트 프레임워크의 Junit 확장기능 지정. Junit 프레임워크의 테스트 실행방법을 확장할 때 사용하는 어노테이션
23. SpringJUnit4ClassRunner : Junit 프레임워크에 이 확장 클래스를 지정해주면 Junit이 테스트를 진행하는 중에 테스트가 사용할 어플리케이션을 만들고 지정해 줌
22. @ContextConfiguration : 테스트 컨텍스트가 자동으로 만들어줄 어플리케이션 컨텍스트의 위치지정. 로케이션을 통해 설정파일 경로를 지정해줄 수도 있고, 로케이션이 없을시 <클래스이름+’-context.xml’ 파일을 사용하는 어플리케이션 컨텍스트로 만들어서 테스트가 사용할 수 있게 해줌. (위의 클래스이름을 예로들면 UserTest-context.xml 로 만들어주면 생략가능)
24. @Autowired : 이것이 붙은 인스턴스 변수가 있으면, 컨텍스트 프레임워크는 컨텍스트 내의 빈을 찾아 타입이 일치하는 빈이 있으면 인스턴스 변수에 주입해준다. 보통 생성자나 수정자 메소드가 필요하지만.. 타입이 두 개 이상 있는 경우에는 변수 이름과 빈의 이름이 같은 것을 찾는다. 변수 이름으로도 빈을 찾을 수 없는 경우에는 예외가 발생함.
- 자동와이어링 : Autowired 와 같이 타입정보를 이용해 빈을 자동으로 가져오는 법
- applicationContext.xml 정의된 빈이 아닌 ApplicationContext가 DI가 되었는데, 스프링 어플리케이션 컨텍스트는 초기화할 때 자기 자신도 빈으로 등록하기에 이게 가능한 것임.
12. 스프링의 Junit 확장기능은 테스트가 실행되기 전에 딱 한번만 어플리케이션 컨텍스트를 만들어두고, 테스트 오브젝트가 만들어 질 때마다 어플리케이션 컨텍스트 자신을 테스트 오브젝트의 특정 필드에 주입(DI). 스프링 컨텍스트 테스트 개수에 상관없이 한번만 만들어서 사용하여 테스트 수행속도는 매우 빨라짐.
13. 스프링 설정파일(ex: applicationContext.xml)의 종류만큼 어플리케이션 컨텍스트를 만들고, 같은 설정 파일을 지정한 테스트에서는 이를 공유하게 한다.
Context는 세번 모두 동일하게 생성됨.
UserTest 오브젝트는 매번 주소값이 다름 : Junit은테스트 메소드를 실행할 때마다 새로운 테스트 오브젝트를 생성하기 때문
ApplicationContext를 주입받는 것이아니라 아예 UserDao빈을 직접 DI받을 수도 있다.
만약 applicationContext.xml 의 DB설정이 운영용DB라고 생각해보자 deleteAll()에 의해 운영용 데이터가 다 날라갈 것이다. 테스트를 위해 applicationContext를 직접 수정해주는 방법도 있겠지만 번거롭고 위험한 방법이다. 평범한 자바 테스트 코드에서도 얼마든지 DI가 가능하다.
26. @DirtiesContext : 해당클래스에서만 상태를 변경한다. 모든 테스트클래스에서 사용하는 어플리케이션컨텍스트를 모두 바꾸는건 좋지 않은 방법이므로. 즉 어플리케이션 컨텍스트 공유를 허용하지 않음. 매번 새로운 어플리케이션 컨텍스트를 만들어 사용한다. (메소드 레벨에서도 사용가능)
38. SingleConnectionDataSource는 스프링이 제공하는 가장 빠른 DataSource이다. 커넥션을 하나만 만들어두고 계속 사용하기 때문에 매우 빠르다. 다중 사용자 환경에서는 사용 불가, 순차적으로 진행되는 테스트에서라면 문제없다.
* XML 설정파일을 수정하지 않고도 재구성할 수 있다. applicationContext의 설정정보를 따라 구성한 오브젝트를 가져와 의존관계를 강제로 변경
* 컨텍스트는 딱 한 개만 만들어지고 모든 테스트에서 공유해서 사용하는 것이 원칙. 변경하지 않는 것이 원칙. 한번 변경하면 모든 클래스에서 변경된 어플리케이션 컨텍스트를 계속 사용한다.
* 하지만 어플리케이션 컨텍스트를 매번 만드는건 조금 찜찜한 일이다.
테스트 코드에서 빈 오브젝트에 수동으로 DI하는 방법은 장점보다 단점이 많다. 코드가 많아져 번거롭기도하고, 어플리케이션 컨텍스트도 매번 새로 만들어야 하는 부담이 있다.
위처럼 test용 설정 파일을 포함하여 2개만들어 진행하는 방법도 있음
35. 아예 스프링 컨테이너를 사용하지 않고 테스트 코드의 수동DI만을 이용해 만들어진 테스트코드이다. @Autowired를 사용하지 않고 직접 DI 해줬다. DataSource를 직접 만드는 번거로움은 있지만 어플리케이션 컨텍스트를 사용하지 않으니 코드는 더 단순해지고 이해하기 편해졌다. Junit은 매번 새로운 오브젝트를 만들기 때문에 매번 새로운 UserDao 오브젝트가 만들어진다는 단점이 있다.
* DI는 객체지향 프로그래밍 스타일이다. 컨테이너가 반드시 필요한 것은 아니다. DI 컨테이너나 프레임워크는 DI를 편하게 적용하도록 도움을 줄 뿐이다.
* 스프링은 비침투적(noninvasive)기술 : 스프링 컨테이너 없는 DI테스트가능. 특정 클래스나 인터페이스를 사용하도록 강제하지 않는다.
14. DI를 이용한 테스트 방법 선택
- 항상 스프링 컨테이너 없이 테스트할 수 있는 방법을 가장 우선적으로 고려한다. 테스트의 수행속도가 가장 빠르고 테스트자체가 간결하다. 오브젝트의 생성과 초기화가 단순하다면 이 방법을 가장 먼저 고려해야한다.
- 복잡한 의존관계라면 어플리케이션 컨텍스트를 따로 만들어 사용한다.
테스트 어플리케이션 컨텍스트를 따로 만들었더라도 예외적인 의존관계를 강제 구성해야한다면 @DirtiesContext 애노테이션을 붙이는 것을 잊지말자.
'스프링' 카테고리의 다른 글
[jdbc]예외처리_전략패턴1 (0) | 2020.10.17 |
---|---|
[spring] junit 3 학습테스트 (0) | 2020.10.13 |
[spring] junit 1 (0) | 2020.10.13 |
[Spring] SpringJDBC_Test (0) | 2020.10.12 |
[Spring] xml Spring IOC (0) | 2020.10.12 |