8.3. Integration testing
org.springframework.test 패키지에서 제공되는 기능들은 아래와 같습니다.
- Spring IoC container caching between test case execution.
- The pretty-much-transparent Dependency Injection of test fixture instances (this is nice).
- Transaction management appropriate to integration testing (this is even nicer).
- A number of Spring-specific inherited instance variables that are really useful when integration testing.
8.3.1. Context management and caching
여러 설정 파일들을 cashing하는 기능입니다. 이게 필요한 이유는 매번 테스트를 할 때마다 설정 파일들을 새로 읽어들이는 비용을 줄이기 위해서 입니다.
AbstractDependencyInjectionSpringContextTests 클래스를 상속하면 다음의 메소드를 꼭 구현하도록 abstract로 되어 있습니다.
protected abstract String[] getConfigLocations();
이 메소드에서 테스트에 필요한 bean설정 파일들(context)을 String 배열로 리턴하도록 구현해 주면 됩니다.
기본적으로 설정파일의 내용이 바꼈을 때만 다시 읽어 들이게 되고 명시적으로 다음 테스트를 하기 전에 다시 읽어 들이게 하고 싶다면 setDirty() 메소드를 사용합니다.
8.3.2. Dependency Injection of test fixtures
AbstractDependencyInjectionSpringContextTests 클래스를 사용하여 bean 설정 파일을 읽어 들이면 DI를 통해서 테스트할 때 필요한 멤버 변수에 값을 세팅할 수 있습니다.
by-type으로 autowiring 설정이 되어있습니다. 따라서 같은 타입의 bean이 여러개일 경우에는 적용이 되지 않을 것입니다.
테스트 클래스의 생성자에서 setPopulateProtectedVariables(true); 를 추가해 주면 protected 접근 지시자의 멤버 변수가 자동으로 세팅되도록 설정할 수 있습니다.
이 때는 autowiring을 사용한 것이 아니라 상속 받은 applicationContext 변수를 통해 직접 bean을 가져와서 세팅하게 됩니다.
8.3.3. Transaction management
DB에 접근하는 테스트를 할 때 문제는 DB에 테스트의 흔적이 남는다는 것인데요. AbstractTransactionalDataSourceSpringContextTests 클래스를 사용하면 테스트를 자동으로 트랜잭션 처리를 해주며 테스트가 끝날때 마다 DB를 롤백시켜줍니다.
이 클래스는 DataSource를 autowiring하게 되어 있으며 by-type이기 때문에 DataSource의 bean 이름은 상관없이 등록되어 있기만 하면 찾아서 DI합니다.
setComplete() 메소드를 사용하면 트랙잭션을 커밋시킬 수 있습니다.
endTransaction() 메소드를 사용하면 테스트 메소드가 끝나기 전에 트랜잭션을 종료시킬 수 있습니다.
8.3.4. Convenience variables
applicationContext :: AbstractDependencyInjectionSpringContextTests 클래스로 부터 상속받는 변수 입니다. bean을 직접 lookup 하거나 context 자체에 대한 테스트를 할 때 사용할 수 있습니다.
jdbcTemplate :: AbstractTransactionalDataSourceSpringContextTests 클래스로 부터 상속받는 변수 입니다.
8.3.5. Java5+ specific support
Java 5.0 이상에서 사용할 수 있는 AbstractAnnotationAwareTransactionalTests 클래스를 상요하면 다음의 어노테이션들을 사용할 수 있습니다.
@DirtiesContext :: 위에서 잠시 언급했었던 setDirty()와 같은 효과를 낼 수 있는 어노테이션으로 해당 테스트 메소드 위에 붙여주면 다음 테스트 메소드를 실행하기 전에 context들을 다시 읽어 들입니다.
@ExpectedException :: 이 어노테이션이 붙은 테스트 메소드에서 발생할 예외 객체 타입을 적어 줍니다. 만약 해당 테스트 메소드에서 해당 예외가 발생하면 테스트는 통과하고 그렇치 않으면 테스트는 실패합니다.
@NotTransactional :: 트랙잰션 관리 대상에서 제외합니다.
@Repeat :: 해당 테스트 메소드를 몇 번 반복해서 테스트할지 지정해 줄 수 있습니다.
위에서 언급했던 세 개의 클래스의 상속 구조 입니다.