LoginSignup
0
0

More than 1 year has passed since last update.

DB名にスキーマが含まれていると DBUnit の @DatabaseSetup とかでテーブルがみつからない

Posted at

いや、普通データベースってスキーマ切るでしょ。
これが「DBUnit スキーマ」とかで探してもほとんど出てこなかったんですよ。なんか Oracle データベースの話しかみんなしてない。なんでやねん。

だめなやつ

TestConfig.java
/**
 * テスト用JDBCドライバのbean
 */
@Configuration
public class TestConfig {
  @Bean
  DataSource dataSource(){
    return dataSourceH2();
  }

  DataSource dataSourceH2() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    builder.setType(EmbeddedDatabaseType.H2)
      .addScript("table/schema.sql").addScript("table/data.sql");
    return builder.build();
  }

  @Bean
  JdbcTemplate jdbcTemplate(DataSource dataSource){
    return new JdbcTemplate(dataSource);
  }
}
schema.sql
create schema sh;
create table sh.test
(
    id int
);
data.sql
insert into
  sh.test (id)
  values (1);
table/init/teble-ordering.txt
sh.test
table/init/sh.test.csv
id
1
2
3
Test.java
@SpringBootTest(classes = {TestConfig.class})
@RunWith(SpringRunner.class)
@DbUnitConfiguration(dataSetLoader = CsvDataSetLoader.class) 
@TestExecutionListeners({
  DependencyInjectionTestExecutionListener.class,
  DbUnitTestExecutionListener.class
})
@TestPropertySource("/application.properties")
@Transactional
public class Test {

  @Autowired
  JdbcTemplate jdbcTemplate;

  @Test
  @DatabaseSetup("/table/init") // ← これをコメントアウトするとちゃんとsqlで初期化した内容がプリントされる
  public void test(){
    System.out.println(jdbcTemplate.queryForList("select * from sh.test"));
  }
}

CsvDataSetLoader の中身は割愛。CSV読めるようにするやつ。

とにかく、 jdbcTemplate から <スキーマ名>.<テーブル名> でアクセスできるもんだからDBUnitからでも同じ感じでアクセスできるもんだと勘違いしていたけどどうにもエラーが出て初期化をしてくれない。

org.dbunit.dataset.NoSuchTableException: sh.test

探した探した。

この stackoverflow は最初の方にみつけてはいたものの、ベストアンサーが「OracleConnection bean を使え」という物だったから「違うんだよなぁH2なんだよなぁ」と思いながらスルーしていた。けど近しいものがこの質問ぐらいしか無かったから繁々と眺めていたら下の方に少し詳しい回答がちゃんとあった。 飛び道具をベストアンサーにするなよfxxk

If you are using the spring-test-dbunit then you need to create an IDatabaseConnection with a specific DBUnit configuration. Following the doc's example I've setup this one for me:
(spring-test-dbunitを使用している場合は、特定のDBUnit構成でIDatabaseConnectionを作成する必要があります。ドキュメントの例に従って、これをセットアップしました。)

書いてあるのはポスグレ。けれどなんとなくちゃんと設定するものがどこかにあって適切に @DbUnitConfiguration に入れてあげればいいのかなぁと思いながら DBUnitのJavadoc にそれっぽいの無いかなぁ。 H2 って名前のついた IDataConnection 持ってるクラス無いかなぁ。って思ってたら ちゃんとありました

public class H2Connection
Constructor and Description
H2Connection(java.sql.Connection connection, java.lang.String schema)

スキーマ指定できるやーん……

うごくやつ

TestConfig.java
@Configuration
public class TestConfig {
  @Bean
  DataSource dataSource(){
    return dataSourceH2();
  }

  DataSource dataSourceH2() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    builder.setType(EmbeddedDatabaseType.H2).addScript("table/scheme.sql").addScript("table/data.sql");
    return builder.build();
  }

  @Bean
  JdbcTemplate jdbcTemplate(DataSource dataSource){
    return new JdbcTemplate(dataSource);
  }

  // DBUnit専用の接続設定を追加
  @Bean
  H2Connection h2Connection() throws DatabaseUnitException, SQLException{
    return new H2Connection(dataSource().getConnection(), "sh");
  }

}

table/init/teble-ordering.txt
test
table/init/test.csv
id
1
2
3

(↑ファイル名変えただけ)

Test.java
@SpringBootTest(classes = {TestConfig.class})
@RunWith(SpringRunner.class)
// databaseConnection に接続設定を追加
@DbUnitConfiguration(databaseConnection = "h2Connection", dataSetLoader = CsvDataSetLoader.class) 
@TestExecutionListeners({
  DependencyInjectionTestExecutionListener.class,
  DbUnitTestExecutionListener.class
})
@TestPropertySource("/application.properties")
@Transactional
public class JsonDatabaseTest {

  @Autowired
  JdbcTemplate jdbcTemplate;

  @Test
  @DatabaseSetup("/table/init")
  public void test(){
    System.out.println(jdbcTemplate.queryForList("select * from sh.test"));
    // ちゃんとCSVの内容が表示される!!!
  }
}

めでたしめでたし。

なんでJDBCと同じ方法でアクセスさせてくれないんですかねぇ!!!!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0