简体   繁体   中英

Hibernate Configuration with Spring MVC for testing

I'm trying to set up testing with an H2 in-memory database for my Spring MVC application.

Right now, all my configuration for Hibernate is in a Java file PersistenceConfig.java and it holds the SessionFactory with all the Hibernate configuration.

However, my testing context is in XML because it was easier that way - is there any way to make this work? Right now, when I run my tests, all I get is errors because it can't connect to MySQL, which it shouldn't even be trying to do.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-4.0.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                           http://www.springframework.org/schema/jdbc
                           http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">

  <!-- annotation support -->
  <context:annotation-config/>

  <!-- support for transaction -->
  <tx:annotation-driven transaction-manager="transactionManager"/>

  <context:component-scan base-package="com.package.configuration" />
  <context:component-scan base-package="com.package.models" />

  <!-- H2 datasource -->
  <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
  </bean>

  <jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
    <jdbc:script location="classpath:reset_database.sql"/>
    <jdbc:script location="classpath:create_testdata.sql"/>
  </jdbc:initialize-database>

  <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <bean id="persistenceConfig" class="com.package.configuration.PersistenceConfig"/>
  <bean id="userDao" class="com.package.models.user.UserDao"/>
</beans>

My tester class looks like

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/test-context.xml",
    "classpath:/spring/spring-security.xml"})
@Transactional
public class UserTest {
  private UserDao userDao = new UserDao();

  private static User user;

  @Autowired
  @Qualifier("sessionFactory")
  private static SessionFactory sessionFactory;

  @BeforeClass
  public static void initUser() {
    user = new User(...);
  }

  @Test
  public void testSave() throws Exception {
    userDao.save(user);
    User foundUser = userDao.findByUuid(user.getUuid());
    assertEquals(foundUser.getUuid(), user.getUuid());
  }
}

The sessionFactory is not being Autowired and the userDao never gets it.

My UserDao calls PersistenceConfig.sessionFactory() in its constructor, and PersistenceConfig supplies it with a sessionFactory that corresponds to MySQL. I need to somehow switch that out for a H2 sessionFactory .

Am I going about this completely wrong?

It appears that when you are injecting you sessionFactory it is loading PersistenceConfig.java with it, generally when you inject one object others dependencies are injected too. If I were you, I would use hibertane.hbm.xml to configure you test connection, it overrides all others configurations...

You are creating the UserDao object yourself

private UserDao userDao = new UserDao();

Spring can only inject an object whose lifecycle it manages.

Get a UserDao bean from your context ( @Autowired it) if you have one (or add one if you don't).

For testing you can use your PersistenceConfig. Instead of setting up a complete new context I would split the distinct beans into @Profile configurations:

 @Profile("test")
 @Configuration
 public class TestConfig {

     @Bean public DataSource dataSource() {
         // return Test bean
     }

 }

 @Profile("production")
 @Configuration
 public class ProductionConfig {

     @Bean public DataSource dataSource() {
         // return productiv bean
     }

 }

@ActiveProfiles("test")
public class DatasourceTest {

    @Test
    public void test() {
        // assertions
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM