2016-07-25 16 views
0

私は自分のアプリケーションのテストを開発しようとしています(私は非常に遅いテストについて知りました...)。私は多くの例を探検し、彼らの誰も私を満足させず、率直に私を少し混乱させてしまった。Spring Hibernate H2 Junit testing - 起動時にスキーマをロードする方法

私が達成しようとしているのは、テストの開始時(既存のMySQLスキーマからのダンプファイル)にimport.sqlをロードし、H2データベースにロードすることです。ここで

が休止状態の設定ファイルである:

org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO:

@Configuration 
@EnableTransactionManagement 
@ComponentScan({ "kamienica.feature" }) 
public class HibernateTestConfiguration { 

    @Autowired 
    ApplicationContext applicationContext; 

    @Bean 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
     sessionFactory.setDataSource(dataSource()); 
     sessionFactory.setPackagesToScan(new String[] { "kamienica" }); 
     sessionFactory.setHibernateProperties(hibernateProperties()); 
     return sessionFactory; 
    } 

    @Bean(name = "dataSource") 
    public DataSource dataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName("org.h2.Driver"); 
     dataSource.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;" 
       + "INIT=CREATE SCHEMA IF NOT EXISTS kamienica;DB_CLOSE_ON_EXIT=FALSE"); 
     dataSource.setUsername("sa"); 
     dataSource.setPassword(""); 

     return dataSource; 
    } 

    private Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); 
     properties.put("hibernate.hbm2ddl.auto", "update"); 
// this is where I tried to load script the first time: 
// properties.put("hibernate.hbm2ddl.import_files", "kamienica.sql"); 
     return properties; 
    } 

    @Bean 
    @Autowired 
    public HibernateTransactionManager transactionManager(SessionFactory s) { 
     HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(s); 
     return txManager; 
    } 
} 

毎回私はメッセージを取得テストを開始しますHHH000262:テーブルが見つかりませんでした:アパート

空白

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = { HibernateTestConfiguration.class }) 
public class BaseTest { 

    private EmbeddedDatabase db; 

    @Autowired 
    private SessionFactory sessionFactory; 

    //second attempt to load sql file 
    @Before 
    public void setUp() throws Exception { 
     db = new EmbeddedDatabaseBuilder().addScript("import.sql").build(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); 
     SessionFactoryUtils.closeSession(sessionHolder.getSession()); 
    } 

} 

:何

を取得しようと、私はすべての私のテストクラスを拡張するために計画されているSQL(休止プロパティを経由して)休止状態の設定では、ファイルだけでなく、スーパークラスでのロードしようとした値SQLファイルをロードして、H2データベースを準備してテストを実行するにはどうしたらいいですか?

+0

、私はこれがあなたのためにやり過ぎであるかどうか知らないが、CI/CDのような状況で、あなたはあなたのためにあなたのDBスキーマを管理するために、フライウェイのようなものを使用したいですそれはテストDBのために構築することは完全に満足しています。 – chrylis

答えて

1

私はこの春のアプローチがあなたを助けてくれることを願っています。最初にリソースディレクトリ(springbootのクラスパス)をプロジェクトのルートにあるsrc/testディレクトリに作成します。 このディレクトリには、data.sqlという名前のフィクスチャSQLデータファイルの配置が開始されます。 次に、同じレベル(同じディレクトリにスクリーンショットを参照)にapplication.propertiesファイルを作成します。ここに示すように、このファイルが読み込まれるべきである。

spring.datasource.url = jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE 
#spring.datasource.url: jdbc:mysql://localhost:3306/yourDB 
#spring.datasource.username = root 
#spring.datasource.password = 

# Hibernate 
hibernate.show_sql: true 
#hibernate.dialect: org.hibernate.dialect.MySQL5Dialec 
spring.jpa.hibernate.ddl-auto=none 

スクリーンショット: enter image description here

今すぐあなたのテスター方法。任意の出力または完全なスタックトレースがなければ、私はあなたを提案することができます唯一の

@RunWith(SpringJUnit4ClassRunner.class) 
.... 
      @Autowired 
      private DataSource ds; //your application.properties 
      @Autowired 
      private WebApplicationContext context; 
      private static boolean loadDataFixtures = true; 
      private MockMvc mockMvc; 
     .... 

     @Before 
     public void setupMockMvc() { 
     mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); 
    }  




     @Before 
      public void loadDataFixtures() { 
       if (loadDataFixtures) { 
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator(context.getResource("classpath:/data.sql")); 
        DatabasePopulatorUtils.execute(populator, ds); 
        loadDataFixtures = false; 
       } 
      } 

@Test 
public void yourmethod() { 
    assertEquals(3, repository.count()); //example 
} 
-1

されています:

  1. あなたはどんな@Test方法を示すされていません。どうやってそのエラーになっていますか?
  2. import.sqlsrc/test/resourcesフォルダにありますか? (テストパスに注意してください)
  3. あなたのSQLスクリプトはうまく構成されていますか?あなたは一度エクスポートを実行しようとしましたか? apartmentテーブルを作成するSQLスクリプトの部分を投稿できますか?

すべてが真であれば、問題は多分SQLを読み込むことではなく、その使用方法やスクリプトの内容、テーブルの名前などです

0

長い「調査」の後、問題はDBUnitのTestNGセットアップのどこかに隠されていると私は結論づけました。

私はそれを単純にして、JUnitテストに切り替えました。ケースの他に

は、ここにも同様の問題がある可能性があります私の作品の設定ファイルである:

@Configuration 
@EnableTransactionManagement 
@ComponentScan({ "kamienica.feature" }) 
public class JUnitConfig { 

    @Bean 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
     sessionFactory.setDataSource(dataSource()); 
     sessionFactory.setPackagesToScan(new String[] { "kamienica" }); 
     sessionFactory.setHibernateProperties(hibernateProperties()); 
     return sessionFactory; 
    } 

    @Bean(name = "dataSource") 
    public DataSource dataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName("org.h2.Driver"); 
     dataSource.setUrl("jdbc:h2:mem:kamienica;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"); 

     dataSource.setUsername("sa"); 
     dataSource.setPassword(""); 
     return dataSource; 
    } 

    private Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); 
     properties.put("hibernate.hbm2ddl.auto", "create"); 
     return properties; 
    } 

    @Bean 
    public HibernateTransactionManager transactionManager(SessionFactory s) { 
     HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(s); 
     return txManager; 
    } 

} 

すべてが今必要とされるリソースフォルダにimport.sqlファイルを挿入することです。 また、各挿入ステートメントは、どれくらい長くても1行になければならないことがわかりました。そうでなければ、ロードされません。

最後に、簡単なテストクラス

@ContextConfiguration(classes = { JUnitConfig.class }) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class ApartmentServiceTest extends AbstractServiceTest{ 

    @Autowired 
    ApartmentService service; 


    @Test 
    public void getList() { 
     List<Apartment> list = service.getList(); 
     System.out.println(list.toString()); 
     assertEquals(5, list.size()); 
    } 
} 
関連する問題