Gradle で Multi-project を作成する ( その10 )( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する2 )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その9 )( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
Shortest way to get File object from resource in Groovy
https://stackoverflow.com/questions/39245934/shortest-way-to-get-file-object-from-resource-in-groovySpring start a transaction with object created by new
https://stackoverflow.com/questions/4707193/spring-start-a-transaction-with-object-created-by-newapplicationContext.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(...)
で手動で Bean を登録する方法を参考にしました。
目次
手順
テストを作成する
最初にテストで利用する CSV ファイルを作成します。sample-cmdapp/src/test/resources/employee.csv を新規作成し、以下の内容を記述します。
"name","age","sex" "高橋 蓮","15","男" "渡辺 結月","24","女"
次に sample-cmdapp/src/main/java/ksbysample/app/samplecmdapp/EmployeeDataCsvToDbLoader.java のテストクラスを作成します。
@SpringBootTest アノテーションが付与されたクラスのテストメソッドを実行するとテストメソッド内の処理が実行される前に CommandLineRunner インターフェースを実装したクラスの run メソッドが実行されてしまうのですが、以下の方法で run メソッドが自動で実行されないようにします。
- EmployeeDataCsvToDbLoader クラスに
@ConditionalOnProperty(value = { "batch.execute" }, havingValue = "EmployeeDataCsvToDbLoader")
アノテーションを付与して、batch.execute=EmployeeDataCsvToDbLoader
が設定されない限り自動で Bean に登録されないようにします。 - EmployeeDataCsvToDbLoader クラスのコンストラクタに渡すオブジェクト(Bean)は、テストクラスのフィールドに
@Autowired
アノテーションを付与して定義しておきます。 - テストメソッドの最初で EmployeeDataCsvToDbLoader クラスのインスタンスを生成してから
context.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(...)
を呼び出して手動で Bean に登録します。手動で登録すると CommandLineRunner#run メソッドは自動で実行されません。
sample-cmdapp/src/test/groovy/ksbysample/app/samplecmdapp/EmployeeDataCsvToDbLoaderTest.groovy が新規作成されますので、以下の内容を記述します。
package ksbysample.app.samplecmdapp import groovy.sql.Sql import ksbysample.lib.doma2lib.dao.EmployeeDao import org.modelmapper.ModelMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.ApplicationContext import spock.lang.Specification import javax.sql.DataSource // 通常は spring.profiles.active は IntelliJ IDEA の JUnit の Run/Debug Configuration と build.gradle に定義するが、 // 今回はテストが1つしかないので @SpringBootTest の properties 属性で指定する @SpringBootTest(properties = ["spring.profiles.active=develop"]) class EmployeeDataCsvToDbLoaderTest extends Specification { @Autowired private ApplicationContext context @Autowired private DataSource dataSource @Autowired private final EmployeeDao employeeDao @Autowired private final ModelMapper modelMapper def sql void setup() { sql = new Sql(dataSource) } void cleanup() { sql.close() } def "EmployeeDataCsvToDbLoader.run メソッドを実行すると employee.csv のデータが employee テーブルに登録される"() { setup: // EmployeeDataCsvToDbLoader クラスは batch.execute=EmployeeDataCsvToDbLoader が指定されていないと Bean として // 登録されず run メソッドが自動で実行されない。テストでは手動で Bean に登録することで run メソッドが自動実行されることを // 回避する。 EmployeeDataCsvToDbLoader employeeDataCsvToDbLoader = new EmployeeDataCsvToDbLoader(employeeDao, modelMapper) employeeDataCsvToDbLoader = (EmployeeDataCsvToDbLoader) context .getAutowireCapableBeanFactory() .applyBeanPostProcessorsAfterInitialization(employeeDataCsvToDbLoader, "employeeDataCsvToDbLoader") // src/test/resources の下の employee.csv の File オブジェクトを取得する def url = getClass().getResource("/employee.csv") def employeeCsvFile = new File(url.toURI()) // employee テーブルからテストデータを削除する sql.execute("delete from employee where name in ('高橋 蓮', '渡辺 結月')") expect: employeeDataCsvToDbLoader.run("-csvfile=${employeeCsvFile.absolutePath}") def results = sql.rows("select name, age, sex from employee where name in ('高橋 蓮', '渡辺 結月')") results == [ [name: "高橋 蓮", age: 15, sex: "男"], [name: "渡辺 結月", age: 24, sex: "女"] ] cleanup: sql.execute("delete from employee where name in ('高橋 蓮', '渡辺 結月')") } }
テストを実行して成功することを確認します。
コマンドラインから実行して動作確認する
employee テーブルにテストデータが登録されていないことを確認した後、
sample-cmdapp-1.0.0-RELEASE.jar が生成されている D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-doma2lib-cmdwebapp\sample-cmdapp\build\libs
に移動してから java -Dspring.profiles.active=develop -Dbatch.execute=EmployeeDataCsvToDbLoader -jar sample-cmdapp-1.0.0-RELEASE.jar -csvfile=D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-doma2lib-cmdwebapp\sample-cmdapp\src\test\resources\employee.csv
コマンドを実行します。
employee テーブルを確認するとテストデータが登録されています。
問題なさそうです。
最後に sample-cmdapp プロジェクトのディレクトリ構成を記載します。
sample-cmdapp-1.0.0-RELEASE.jar の中身を見てみると以下のようになっており doma2-lib-1.0.0-RELEASE.jar が lib ディレクトリの下に入っています。
補足
sample-cmdapp でも Flyway は動作している
現在の設定では sample-cmdapp を実行した時も Flyway は動作しています。確認してみます。
docker-compose down
コマンドを実行後、docker/mysql/data の下をクリアします。
docker-compose.yml の flyway の設定をコメントアウトした後、
version: '3' services: .......... # flyway: # image: boxfuse/flyway:${FLYWAY_VERSION}-alpine # container_name: flyway # environment: # - TZ=Asia/Tokyo # volumes: # - ./doma2-lib/src/main/resources/db/migration:/flyway/sql # command: -url=${FLYWAY_URL} -user=${FLYWAY_USER} -password=${FLYWAY_PASSWORD} -connectRetries=60 migrate # depends_on: - mysql # 下の3行は debug 用 # うまく動かない時はコメントアウトを解除した後、 # docker exec -it flyway /bin/sh # で接続してから # flyway <command に記述した文字列> # を実行してみる # # entrypoint: /bin/sh # stdin_open: true # tty: true
docker-compose up -d
コマンドを実行します。
adminer にログインして sampledb を見るとテーブルは何もありませんが、
コマンドラインから java -Dspring.profiles.active=develop -Dbatch.execute=EmployeeDataCsvToDbLoader -jar sample-cmdapp-1.0.0-RELEASE.jar -csvfile=D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-doma2lib-cmdwebapp\sample-cmdapp\src\test\resources\employee.csv
を実行してから、
sampledb を確認すると employee と flyway_schema_history の2つのテーブルが作成されており、
employee テーブルにも doma2-lib/src/main/resources/db/migration/V1__create_table.sql の2件と sample-cmdapp/src/test/resources/employee.csv の2件の合計4件のデータが登録されています。
履歴
2019/05/01
初版発行。