Spock ライクにテストデータを表現する

過去にこんな記事 ([Spock ちっくにテストデータを挿入してみた話](http://qiita.com/yo1000/items/3a9cd90f768772f6af10)) も書きましたが、最近は [DBUnit](http://dbunit.sourceforge.net/) だけでなく、[DbSetup](http://dbsetup.ninja-squad.com/) を使用することも多かったので、当時作成したモジュールをアップデートしてみました。

なかなかいい感じにデータ表現できるようになったので、ご報告。

# 環境

- Java 1.8.0_91
- Maven 3.3.9
- Groovy 2.4.7
- Spock 1.1-groovy-2.4-rc-1
- DbSetup 2.1.0
- DBUnit 2.5.3

```
$ ./mvnw --version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: /Users/yo1000/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.5", arch: "x86_64", family: "mac"
```

# 依存関係追加

`pom.xml` に依存関係を追加します。DbSetup、または DBUnit のうち、いずれか使用する方を追加してください。(両方追加されていても支障ありません。)

以下抜粋。

```xml:pom.xml&nbsp;&lt;dependencies&gt;
<!-- dbspock -->
<dependency>
  <groupId>com.yo1000</groupId>
  <artifactId>dbspock-core</artifactId>
  <version>1.1.0.RELEASE</version>
  <scope>test</scope>
</dependency>
<!-- for DbSetup -->
<dependency>
  <groupId>com.yo1000</groupId>
  <artifactId>dbspock-dbsetup</artifactId>
  <version>1.1.0.RELEASE</version>
  <scope>test</scope>
</dependency>
<!-- for DBUnit -->
<dependency>
  <groupId>com.yo1000</groupId>
  <artifactId>dbspock-dbunit</artifactId>
  <version>1.1.0.RELEASE</version>
  <scope>test</scope>
</dependency>

<!-- Groovy spock -->
<dependency>
  <groupId>org.codehaus.groovy</groupId>
  <artifactId>groovy-all</artifactId>
  <version>2.4.7</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.spockframework</groupId>
  <artifactId>spock-core</artifactId>
  <version>1.1-groovy-2.4-rc-1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.spockframework</groupId>
  <artifactId>spock-spring</artifactId>
  <version>1.1-groovy-2.4-rc-1</version>
  <scope>test</scope>
</dependency>

<!-- DbSetup -->
<dependency>
  <groupId>com.ninja-squad</groupId>
  <artifactId>DbSetup</artifactId>
  <version>2.1.0</version>
  <scope>test</scope>
</dependency>

<!-- DBUnit -->
<dependency>
  <groupId>org.dbunit</groupId>
  <artifactId>dbunit</artifactId>
  <version>2.5.3</version>
  <scope>test</scope>
</dependency>
```

```xml:pom.xml&nbsp;&lt;repositories&gt;
<repository>
  <id>com.yo1000</id>
  <name>yo1000 maven repository</name>
  <url>http://yo1000.github.io/maven/</url>
</repository>
```

# データ表現

このモジュールを使用することで、テーブル名、カラム名、レコードを以下のように表現できます。

```:groovy
テーブル名A {
    col '列名A1'    | '列名A2'    | '列名A3'    | ...
    row '行A1:値A1' | '行A1:値A2' | '行A1:値A3' | ...
    row '行A2:値A1' | '行A2:値A2' | '行A2:値A3' | ...
    ...
}

テーブル名B {
    col '列名B1'    | '列名B2'    | '列名B3'    | ...
    row '行B1:値B1' | '行B1:値B2' | '行B1:値B3' | ...
    row '行B2:値B1' | '行B2:値B2' | '行B2:値B3' | ...
    ...
}
```

`col`、`row` は予約語的な扱いで、それぞれ、カラム行の前と、レコード行の前に置く必要があります。実際には対応する名前のメソッドが用意されているだけですが、Groovy で記述することで、メソッドの `()` を省略でき、このような記述が可能になっています。

# デモコード

実際のコードを確認します。ここでは、Spock を使用したテストコードの、`setup` 部分のみ抜粋して紹介します。

全文については、以下をご確認ください。
https://github.com/yo1000/dbspock/blob/973e269862ef6e58309c2f575d1b6ff96edf5052/dbspock-specs/src/test/groovy/com/yo1000/dbspock/DbspockSpec.groovy

## DbSetup

DbSetup によるテストの場合は、以下のように記述します。

```groovy
setup:
def insertOps = DbspockOperations.insertInto {
    test_table {
        col 'test_int' | 'test_str' | 'test_date'
        row 100        | 'test1'    | '2016-09-26 23:20:01.0'
        row 200        | 'test2'    | '2016-09-26 23:20:02.0'
        row 300        | 'test3'    | '2016-09-26 23:20:03.0'
    }
}

def destination = new DriverManagerDestination(URL, USERNAME, PASSWORD)
new DbSetup(destination,
        Operations.sequenceOf(
                Operations.truncate('test_table'),
                insertOps
        )
).launch()
```

## DBUnit

DBUnit によるテストの場合は、以下のように記述します。

```groovy
setup:
def dataSet = DbspockLoaders.loadDataSet {
    test_table {
        col 'test_int' | 'test_str' | 'test_date'
        row 100        | 'test1'    | '2016-09-26 23:20:01.0'
        row 200        | 'test2'    | '2016-09-26 23:20:02.0'
        row 300        | 'test3'    | '2016-09-26 23:20:03.0'
    }
}

def databaseTester = new JdbcDatabaseTester(Driver.class.getName(), URL, USERNAME, PASSWORD)
databaseTester.setUpOperation = DatabaseOperation.CLEAN_INSERT

databaseTester.dataSet = dataSet
databaseTester.onSetup()
```

# おわりに

Groovy の表現力により、とても自然な形でテストデータを表現できるようになりました。

今回のモジュールは、Maven モジュールの他に、以下でコードも公開しているので、より詳しく内容について知りたい場合は、こちらも併せてご確認ください。

https://github.com/yo1000/dbspock