db-unit은 XML 파일을 이용해서 테스트 데이터를 초기화할 수 있는 기능을 제공하기 때문에, 서버 수준에서 통합 테스트를 진행할 때 매우 유용하게 사용하고 있다. db-unit의 XML 설정은 다음과 같이 테이블 이름과 컬럼 이름을 사용해서 초기화에 사용할 데이터를 입력한다. 태그는 테이블을 나타내고, 속성은 컬럼을, 속성의 값은 컬럼의 값을 의미한다.
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<POOL ID="1" SUBNET_CONFIG_ID="1" RANGE_FROM="10.0.10.2" RANGE_TO="10.0.10.255" />
<POOL ID="2" SUBNET_CONFIG_ID="2" RANGE_FROM="10.0.20.2" RANGE_TO="10.0.20.255"
SUBNETMASK="255.255.255.0" GATEWAY="10.0.20.1" DNSLIST="1.2.3.4" />
<POOL ID="3" SUBNET_CONFIG_ID="3" RANGE_FROM="10.0.30.2" RANGE_TO="10.0.30.255" />
</dataset>
spring-db-unit을 사용하면 db-unit을 스프링과 연동해서 사용할 수 있다. 예를 들어, 약간의 애노테이션 설정으로 스프링에 설정한 DataSource를 사용해서 db-unit을 실행할 수 있다. 다음은 spring-db-unit이 제공하는 @DatabaseSetup 애노테이션의 사용 예이다.
@ContextConfiguration("classpath:spring/*.xml")
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@DatabaseSetup(value = "/ConfigTestData.xml", type = DatabaseOperation.CLEAN_INSERT)
@RunWith(SpringJUnit4ClassRunner.class)
public class UsableIpRangeFinderIntTest {
...
}
그런데, spring-db-unit을 사용할 때 주의할 점은 db-unit의 XML 처리 방식에 있다. 예를 들어, 다음과 같은 XML 설정을 사용하면 당연히 SUBNETMASK 컬럼과 GATEWAY 컬럼의 값이 사용될거라 생각되겠지만, 실제로는 ID, SUBNET_CONFIG_ID, RANGE_FROM, RANGE_TO 컬럼의 값만 제대로 처리된다.
<dataset>
<POOL ID="1" SUBNET_CONFIG_ID="1" RANGE_FROM="10.0.10.2" RANGE_TO="10.0.10.255" />
<POOL ID="2" SUBNET_CONFIG_ID="2" RANGE_FROM="10.0.20.2" RANGE_TO="10.0.20.255"
SUBNETMASK="255.255.255.0" GATEWAY="10.0.20.1" DNSLIST="1.2.3.4" />
</dataset>
SUBNETMASK 컬럼과 GATEWAY 컬럼이 처리되지 않는 이유는, 가장 첫 번째로 만난 태그의 속성 목록만을 컬럼으로 인식하기 때문이다. 즉, 위 XML 파일의 경우 <POOL> 태그 중 첫 번째 <POOL> 태그에 정의된 속성만 컬럼으로 처리하기 때문에, 두 번째 <POOL> 태그에만 존재하는 SUBNETMASK와 GATEWAY는 컬럼으로 인식되지 않는다.
태그에 포함된 모든 속성을 컬럼으로 처리하려면 db-unit의 컬럼 센싱이라는 설정을 활성화해야 하는데, (아직까지) spring-db-unit은 컬럼 센싱을 활성화해주는 설정을 지원하지 않고 있다. 이 컬럼 센싱 기능을 활성화려면 spring-db-unit의 DataSetLoader의 커스텀 구현 클래스를 만들어야 한다. 컬럼 센싱 기능을 활성화하기 위한 커스텀 DataSetLoader 클래스의 구현 예는 다음과 같다.
import com.github.springtestdbunit.dataset.AbstractDataSetLoader;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.springframework.core.io.Resource;
import java.io.InputStream;
public class ColumnSensingFlatXmlDataSetLoader extends AbstractDataSetLoader {
@Override
protected IDataSet createDataSet(Resource resource) throws Exception {
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
InputStream inputStream = resource.getInputStream();
try {
return builder.build(inputStream);
} finally {
inputStream.close();
}
}
}
커스텀 구현 클래스를 사용하려면 @DbUnitConfiguration 애노테이션을 추가로 설정해주면 된다.
@ContextConfiguration("classpath:spring/*.xml")
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@DatabaseSetup(value = "/ConfigTestData.xml", type = DatabaseOperation.CLEAN_INSERT)
@DbUnitConfiguration(dataSetLoader = ColumnSensingFlatXmlDataSetLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class UsableIpRangeFinderIntTest {
...
}
이제 XML 설정에 있는 모든 속성을 컬럼으로 사용하기 때문에, 특정 테이블을 위한 첫 번째 태그에 속성이 존재하지 않더라도 컬럼에 올바르게 값이 설정된다.