2016-07-25 94 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()); 
    } 
}