JUnit은 각각의 테스트가 독립적으로 존재할 수 있게 하기 위해
테스트 메서드마다 서로 다른 오브젝트를 만들어서 실행되게 한다.
하지만 이 경우가 스프링에서는 문제가 될 수 있는데
애플리케이션 컨텍스트를 테스트 오브젝트마다 반복적으로 만들기 때문에
빈이 많아지고 설정이 복잡해지는 경우에는 컨텍스트 생성에 시간이 많이 소요된다.
또한 여러 테스트가 함께 참조해야할 애플리케이션 컨텍스트를
오브젝트 레벨에 저장해두면 각각 다른 컨텍스트를 참조하게 되어 곤란하다.
이를 위해서 JUnit은 테스트 클래스 전체에서 딱 한 번만 실행되는
@BeforeClass 스태틱 메서드라는 기능을 제공한다.
물론 이 기능으로도 가능하지만 스프링에서 제공하는 더 좋은 방법이 있다.
스프링 테스트 컨텍스트 프레임워크
적용하기
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/applicationContext.xml")
public class UserDaoTest {
@Autowired
ApplicationContext context;
//생략
@Before
public void setUp() {
this.dao = this.context.getBean("userDao", UserDao.class);
//생략
}
}
@RunWith 어노테이션은 JUnit 테스트 실행 방법을 확장할 때 사용하는 어노테이션으로
SpringJUnit4ClassRunner라는 확장 클래스를 지정하여 해당 클래스가
테스트 중에 사용할 애플리케이션 컨텍스트를 만들고 관리해준다.
@ContextConfiguration 어노테이션은 애플리케이션 컨텍스트의 설정파일의 위치를 지정한다.
이렇게 간단하게 하나의 테스트 클래스 내에서 하나의 테스트용 애플리케이션 컨텍스트를 공유할 수 있다.
또한 @ContextConfiguration 어노테이션의 설정파일이 같은 경우에는
같은 애플리케이션 컨텍스트로 보고 서로 다른 테스트 클래스 간이라도
하나의 애플리케이션 컨텍스트를 공유하게 된다.
즉, 설정 파일의 종류만큼만 애플리케이션 컨텍스트를 생성하는 것이다.
@Autowired
해당 어노테이션은 변수 타입과 일치하는 컨텍스트 내의 빈을 찾아서 일치하는 경우
별도의 DI 설정 없이 변수에 주입해주는데, 이러한 방법을 타입에 의한 자동 와이어링이라 한다.
하지만 위의 코드에서는 애플리케이션 컨텍스트 타입의 변수에 해당 어노테이션을 적용하여
제 3자로서 의존관계를 주입하던 애플리케이션 컨텍스트가 역으로 의존관계 주입이 되버렸다.
이는 애플리케이션 컨텍스트도 빈이기 때문인데
애플리케이션 컨텍스트는 초기화할 때 자기 자신도 빈으로 등록한다.
애플리케이션 컨텍스트를 받을 수 있다는 것은 컨텍스트에 등록된 모든 빈들을
getBean을 사용하지 않고도 직접 의존관계 주입을 받을 수도 있다는 것이다.
하지만 타입과 일치하는 빈이 두 개 이상인 경우에는 사용 할 수 없다.
의존관계 주입과 테스트
효율적인 테스트를 손쉽게 만들기 위해서는 작은 단위의 대상에 대해 독립적으로 테스트를 해야 하는데
이를 위해서는 테스트에도 DI를 적용할 수 있다.
1. 테스트 코드에 의한 DI
수정자 메서드는 테스트 코드에서 얼마든지 호출하여 사용할 수 있기 때문에
이를 이용해서 테스트 코드에서 직접 의존관계를 주입할 수 있는데,
테스트 코드에서 의존관계를 변경할 수 있게 된다는 말이다.
설정파일을 수정하지 않고도 의존관계를 상황에 맞게 수정할 수 있지만
한 번 바꾼 의존관계는 남아있는 모든 테스트에 적용되기 때문에 잘 사용해야 한다.
하지만 이러한 문제를 해결하기 위해 @DirtiesContext 어노테이션을 사용하여
의존관계를 바꾸는 테스트가 수행을 마친 후에
새로운 애플리케이션 컨텍스트를 생성하여 나머지 테스트들을 수행하게 할 수 있다.
2. 테스트용 DI 설정하기
위의 방법은 매번 새로운 애플리케이션 컨텍스트를 만들어야 하기 때문에 효과적이지 못하다.
그래서 애초에 실제 서버에서 사용될 설정파일과 테스트용으로 사용될 설정파일을
각각 따로 만들어서 사용하는 것이 효과적이다.
3. 스프링 컨테이너 사용하지 않고 DI 테스트 하기
초반에 작성했던 코드처럼 테스트 코드에서
상황에 맞게 직접 의존관계를 주입하여 테스트 할 수 있다.
DI를 통해 오브젝트들의 관심사를 분리하고 의존성을 낮췄기 때문에
이렇게 애플리케이션 컨텍스트를 만드는 번거로움을 없애 테스트 시간을
절약할 수 있는 테스트 코드를 짤 수도 있다.
테스트 방법 선택하기
위의 세 가지 테스트 방법들은 각각의 장단점이 있기 때문에
모든 방법을 상황에 맞춰 유용하게 사용할 수 있다.
항상 우선적으로는 테스트 수행 속도가 가장 빠르고 간결한
스프링 컨테이너를 사용하지 않는 테스트 방법을 고려하는 것이 좋다.
하지만 여러 오브젝트와 복잡한 의존관계를 갖고 있는 오브젝트의
테스트를 수행해야 하는 경우에는 스프링의 설정을 이용한
DI 방식의 테스트를 사용하는 것이 편리하다.
예외적인 의존관계를 강제로 구성해서 테스트를 해야하는 경우에는
수동으로 의존관계를 주입하는 방식을 사용하는 것이 좋다.
'Back-End > Spring' 카테고리의 다른 글
전략 패턴 최적화 하기 (0) | 2023.06.13 |
---|---|
템플릿 적용하기 (0) | 2023.06.13 |
JUnit 자세히 알아보기 (0) | 2023.06.08 |
테스트 (0) | 2023.06.07 |
XML 설정 (0) | 2023.06.07 |