2016-07-25 95 views
0

我試圖爲我的應用程序開發測試(我發現了非常晚的測試...),我被卡住了,基本配置。我已經通過很多例子搜索,沒有一個人滿意我,並坦率地讓我有點困惑。春季休眠H2 Junit測試 - 如何加載架構開始

我想要實現的是加載import.sql開始測試(這是從現有的MySQL模式轉儲文件)並將其加載到H2數據庫中。

這裏是hibernate的配置文件:

@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; 
    } 
} 

每次我開始測試時,我得到一個消息:

org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata信息: HHH000262:表未找到:公寓

而且我得到空/ null試圖在超這我所有的測試類計劃延伸到獲取任何

我試圖加載在Hibernate的配置(通過Hibernate屬性)的SQL文件,以及當值:

@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文件並準備H2數據庫來執行測試?

+0

我不知道這是否是矯枉過正你,但在CI/CD情況下你會使用類似遷飛來管理你的數據庫模式爲你,並且非常樂意爲測試數據庫構建它。 – chrylis

回答

1

我希望這種春季靴子的方法會幫助你。首先在項目的根目錄下的src/test目錄中創建一個資源目錄(用於springboot的類路徑)。 在此目錄中,您將開始放置名爲say 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腳本是否合適?你有沒有試過運行一次導出?你可以發表的SQL腳本部分創建apartment表嗎?

如果一切都是真的,也許問題不是關於加載的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文件中的資源文件夾中。 我也發現每個插入語句都必須在一行中,不管它多長時間,否則它將不會被加載。

最後一個簡單的測試類:

@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()); 
    } 
}