JUnit, Unitils 를 이용하여 데이터베이스 관련 테스트 수행에 필요한 테이블 스키마를 자동으로 관리해주는 기능을 소개한다.
이 기능은 다음의 단계로 활용할 수 있다.
Maven Project 인 경우에는 아래와 같은 dependency 를 설정하면 된다.
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils</artifactId> <version>2.2</version> <scope>test</scope> </dependency>
Unitils 를 이용하면 위처럼 TestDataSource 를 생성하거나, spring+unitils 조합의 DataSource 를 생성함과 동시에 테스트에 필요한 테이블을 생성하고 초기 데이터를 입력할 수 있다.
먼저 이를 위해서는 테이블 생성 스크립트를 준비하고, 이를 적절한 폴더에 위치시켜야 하며 unitils.properties 파일을 설정해야 한다.
# Properties for the PropertiesDataSourceFactory database.driverClassName=org.hsqldb.jdbcDriver database.url=jdbc:hsqldb:hsql://localhost/sampledb database.userName=sa database.password=
Unitils 는 여기서 언급된 종류의 DBMS를 지원하며 여기에 없는 DBMS 는 unitils 의 기능을 제한적으로 사용할 수 밖에 없으므로 설정하지 않는다.
# This property specifies the underlying DBMS implementation. Supported values are 'oracle', 'db2', 'mysql', 'hsqldb' and 'postgresql'. # The value of this property defines which vendor specific implementations of DbSupport and ConstraintsDisabler are chosen. database.dialect=hsqldb # A comma-separated list of all used database schemas. The first schema name is the default one, if no schema name is # specified in for example a dbunit data set, this default one is used. # A schema name is case sensitive. database.schemaNames=PUBLIC # Type of transaction manager that should be created: # simple: a simple transaction manager that wraps the datasource to control transactions # spring: a transaction manager that delegates actions to the transaction manager that is configured in the current spring context # auto: this will first try to load the spring transaction manager. if spring is not available, it will load the simple transaction manager transactionManager.type=auto
이 때 사용하는 sql 문을 저장해 둔 디렉토리 경로를 설정한다.
dbMaintainer.disableConstraints.enabled 는 단위 테스트 수행 시 테이블간의 제약 조건을 제외한다는 것으로 true 로 지정하면 이 관계를 임시적으로 끊는 등의 별도 작업없이 진행이 되므로 유용하다.
# If set to true, the DBMaintainer will be used to update the unit test database schema. This is done once for each # test run, when creating the DataSource that provides access to the unit test database. updateDataBaseSchema.enabled=true # Comma separated list of directories and files in which the database update scripts are located. Directories in this # list are recursively searched for files. dbMaintainer.script.locations=src/test/resources/META-INF/persistence/maintenance/hsqldb # If set to true, an implementation of org.unitils.dbmaintainer.constraints.ConstraintsDisabler will be used to disable # the foreign key and not null constraints of the unit test database schema. # The ConstraintsDisabler is configured using the properties specified below. The property with key 'database.dialect' # specifies which implementation is used. dbMaintainer.disableConstraints.enabled=true
database.driverClassName=org.hsqldb.jdbcDriver database.url=jdbc:hsqldb:hsql://localhost/sampledb database.userName=sa database.password= DatabaseModule.Transactional.value.default=disabled database.dialect=hsqldb database.schemaNames=PUBLIC transactionManager.type=auto updateDataBaseSchema.enabled=true dbMaintainer.script.locations=src/test/resources/META-INF/persistence/maintenance/hsqldb dbMaintainer.disableConstraints.enabled=true
위와 같이 설정하고, 단순히 unitils 의 TestDataSource 를 선언하기만 하면 되고, 하나 이상의 테스트 메소드가 있어야 한다.
/** * unitils.properties 에 설정 된 database 접근 정보를 기반으로 * 테스트 용 DataSource 를 만든 후 자동으로 injection 해 준다. * (unitils.properties 파일의 위치와 이름은 변경할 수 없다.) * * @see unitils.properties * */ @TestDataSource private DataSource dataSource; /** * dataSource를 정상적으로 get 했는지를 확인한다. */ @Test public void checkTestDataSource() { assertNotNull("dataSource를 정상적으로 get 했는지를 확인한다.", dataSource); }
아래와 같은 작업이 실행 된 로그를 확인할 수 있다.
정보: Creating data source. Driver: org.hsqldb.jdbcDriver, url: jdbc:hsqldb:hsql://localhost/sampledb, user: sa, password: <not shown> 2009. 4. 23 오후 4:04:36 org.unitils.database.DatabaseModule updateDatabase 정보: Checking if database has to be updated. 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.version.impl.DefaultExecutedScriptInfoSource checkExecutedScriptsTable 경고: Executed scripts table "PUBLIC"."DBMAINTAIN_SCRIPTS" doesn't exist yet or is invalid. A new one is created automatically. 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.structure.impl.DefaultConstraintsDisabler disableConstraints 정보: Disabling contraints in database schema PUBLIC 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.clean.impl.DefaultDBClearer clearSchemas 정보: Clearing (dropping) database schema PUBLIC 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.DBMaintainer updateDatabase 정보: Database update scripts have been found and will be executed on the database. 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.clean.impl.DefaultDBCleaner cleanSchemas 정보: Cleaning database schema PUBLIC 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.DBMaintainer executeScripts 정보: Executing script script/001_initial.sql 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.structure.impl.DefaultConstraintsDisabler disableConstraints 정보: Disabling contraints in database schema PUBLIC 2009. 4. 23 오후 4:04:36 org.unitils.dbmaintainer.structure.impl.DefaultSequenceUpdater updateSequences 정보: Updating sequences and identity columns in database schema PUBLIC