とあるエンジニア系ライダーの日常

Webエンジニアの話、バイクの話

SpringのUTにDBSetupを使ってみたら良かった

はじまり

DBのテスト、できればきれいに書きたい。

ということで

  • insert文とかベタ書き : なんか嫌だ
  • DBUnit : 使ったことはあるけど、ファイル参照嫌だ
  • オレオレUtil : 再利用性がない!

ということで、DBSetupというのを見つけた。

データは「流れるようなインタフェース(Fluent Interface)」で作成する。

この一文に惚れたからだ。

自分の環境

  • spring-boot
  • JPARepository
  • JUnit4

これに合うようにやってみた。

テストされる側

単にデータを全部返すだけのメソッド

@Service
@Transactional
public class MyDataService {

@Autowired
MyDataRepository myDataRepository;

public List<MyData> findAll() {
return myDataRepository.findAll(new Sort(Sort.Direction.ASC, "id"));
}
}

使ってみた

とりあえずversion2.0をimport

pom.xml

<!-- https://mvnrepository.com/artifact/com.ninja-squad/DbSetup -->
<dependency>
<groupId>com.ninja-squad</groupId>
<artifactId>DbSetup</artifactId>
<version>2.0.0</version>
</dependency>

SpringBootはテスト時はtest/resources/application.propertiesがあったらそちらを読み込むので作成。

spring.datasource.url=jdbc:mysql://192.168.33.10/mytestdatabase
spring.datasource.username=testuser
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

これで通常環境は汚染されない。

DataSourceどうやってとってくるかで迷ったけど、普通に@Autowire

DataSouce取ればテスト用のDataSouceが入ってた。

@RunWith(SpringRunner.class)
@SpringBootTest

この辺のDIのおかげかな。

あとは、データの定義、これがカッコイイ!!!

クラス内にデータがどうなっているか収まるのでDBUnitよりも読みやすい!!!

public static final Operation DELETE_ALL =
Operations.deleteAllFrom("mydata");

public static final Operation INSERT =
Operations.insertInto("mydata")
.columns("id", "name")
.values("1","Tanaka")
.values("2","Yoshida")
.values("3","Suzuki")
.build();

で、Beforeでデータをセットしてやると。

@Before
public void before(){
Destination dest = new DataSourceDestination(dataSource);
Operation ops = Operations.sequenceOf(DELETE_ALL, INSERT);
DbSetup dbSetup = new DbSetup(dest, ops);
dbSetup.launch();
}

sequenceOfで生成したOperationを繋げられるので楽!

あとは普通にテストすれば

@Autowired
MyDataService myDataService;

@Test
public void canFindAll() throws Exception {
List<MyData> myData = myDataService.findAll();
assertThat(myData.get(0).getId(),is(1));
assertThat(myData.get(0).getName(),is("Tanaka"));
}

オールグリーン!!!

まぁ、使ってみたかっただけのテストなんで、テスト自体は雑ですが。

なんて素敵なんだろう。この流れるようなインターフェース。

もうDBUnitのことなんて忘れよう!

DBのテストをこれで切り出して、

その部分がテストされていればあとはMockitoとかでMockすればいいし。

うん、なんか結局惚れた!