くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

SpringBoot/SpringMVCでRepositoryのテストを楽にするspring-test-dbunit

JavaでDBのテストを書くなら、もちろんDbUnit

さらに、Spring Testing Frameworkと一緒に使うなら、Spring Test DBUnit!

なのですが、環境構築する際にはまったので、そのときの備忘録φ(..)メモメモ

最終的にはこんな感じでアノテーションベースでDBUnitが使えます

public class TestFooRepository extends AbstractRepositoryTest {
  @Autowired private FooRepository repo;

  @Test
  @DatabaseSetup("/db/test001/setup.xml")
  @ExpectedDatabase("/db/test001/expected.xml")
  public void test001() {
    List<FooEntity> foos = repo.findAll();

    assertThat(foos.size(), is(4));
  }
}

まずは、build.gradleのdependencies

dependencies {
  ・・・
  testCompile('org.springframework.boot:spring-boot-starter-test')
  testCompile 'com.github.springtestdbunit:spring-test-dbunit:1.3.0'
  testCompile 'org.dbunit:dbunit:2.5.2'
}

DBUnitで使うデータソースの設定

公式だと、xmlのBean定義を使うようになっているけど、SpringBootで使いたいのでアノテーションベースで設定

public class TestDataSourceConfig {
  private static final String URL = "jdbc:postgresql://localhost:5432/test";
  private static final String USERNAME = "postgres";
  private static final String PASSWORD = "postgres";

  @Bean
  public DataSource dataSource() {
    return new DriverManagerDataSource(URL, USERNAME, PASSWORD);
  }
}

あとはJUnitに適宜アノテーションをつければ完了!

@RunWith(SpringJUnit4ClassRunner.class)
@EnableWebSecurity
@SpringApplicationConfiguration(classes = {
  HogeApplication.class,
  TestDataSourceConfig.class
})
@TestExecutionListeners({
  DependencyInjectionTestExecutionListener.class,
  DirtiesContextTestExecutionListener.class,
  TransactionalTestExecutionListener.class,
  DbUnitTestExecutionListener.class
})
@Transactional
public class TestFooRepository extends AbstractRepositoryTest {
  @Autowired private FooRepository repo;

  @Test
  @DatabaseSetup("/db/test001/setup.xml")
  @ExpectedDatabase("/db/test001/expected.xml")
  public void testFindAll() {
    List<FooEntity> foos = repo.findAll();

    assertThat(foos.size(), is(4));
  }
}

(おまけ) DBUnitのDataSetをCSVでつくりたい

デフォルトのデータセットXML

CSVやほかの形式にしたい場合には、DataSetLoaderをカスタムすればよいらしい。

public class CsvDataSetLoader extends AbstractDataSetLoader{

  @Override
  protected IDataSet createDataSet(Resource resource) throws Exception {
    return new CsvURLDataSet(resource.getURL());
  }
}

自作したDataSetLoaderを使う際は、@DbUnitConfigurationで指定すればOK

【注意】@DatabaseSetupなどの引数は末尾に/を付けないと、失敗する

@RunWith(SpringJUnit4ClassRunner.class)
// ・・・中略
@DbUnitConfiguration(dataSetLoader = CsvDataSetLoader.class)
@Transactional
public class TestFooRepository extends AbstractRepositoryTest {
  @Autowired private FooRepository repo;

  @Test
  @DatabaseSetup("/db/test001/setup/")
  @ExpectedDatabase("/db/test001/expected/")
  public void testFindAll() {
   // 略
  }
}

以上!!

参考になる書籍

Spring Boot 2 プログラミング入門

Spring Boot 2 プログラミング入門

【宣伝】複数言語へ一括翻訳できる文章・単語の管理アプリ『トランスノート』をリリースしました!

f:id:wannabe-jellyfish:20181123102921p:plain:w400

トランスノート|https://trans-notes.net/:plain

アプリやサービスの多言語対応をサポートしてくれるWebサービスです。

メッセージごとにIDをつけれるので、メッセージ一覧の作成・管理に利用できて、
AndoridのXML形式とか、ファイルをそのまま配置できるとこまでやってくれます。

詳しい内容はこちらの記事で。 wannabe-jellyfish.hatenablog.com

参考にしたサイト様