Статьи

Тестирование Spring и Hibernate без XML

Я очень заинтересован в улучшениях в Spring 3, которые в конечном итоге позволят вам перейти от XML к простой конфигурации Java при надлежащей поддержке со стороны IDE и компилятора. Это не меняет того факта, что Spring — огромный набор, и иногда он может найти то, что вам нужно, может занять некоторое время.

Модульные тесты без XML в Hibernate — одна из таких вещей. Я знал, что это возможно, но мне потребовалось более 5 минут, чтобы найти все фрагменты, поэтому здесь я записываю это.

Я собираюсь инициализировать все мои bean-компоненты в классе @Configuration следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Configuration
@EnableTransactionManagement
public class TestRepositoryConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
                .setName("Nuts").build();
    }
 
    @Bean
    public LocalSessionFactoryBean sessionFactoryBean() {
        LocalSessionFactoryBean result = new LocalSessionFactoryBean();
        result.setDataSource(dataSource());
        result.setPackagesToScan(new String[] { "pl.squirrel.testnoxml.entity" });
 
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        result.setHibernateProperties(properties);
        return result;
    }
 
    @Bean
    public SessionFactory sessionFactory() {
        return sessionFactoryBean().getObject();
    }
 
    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager man = new HibernateTransactionManager();
        man.setSessionFactory(sessionFactory());
        return man;
    }
 
    @Bean
    public OrderRepository orderRepo() {
        return new OrderRepository();
    }
}

… И мой тест может выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback = true)
@ContextConfiguration(classes = { TestRepositoryConfig.class })
@Transactional
public class OrderRepositoryTest {
    @Autowired
    private OrderRepository repo;
 
    @Autowired
    private SessionFactory sessionFactory;
 
    @Test
    public void testPersistOrderWithItems() {
        Session s = sessionFactory.getCurrentSession();
 
        Product chestnut = new Product("Chestnut", "2.50");
        s.save(chestnut);
        Product hazelnut = new Product("Hazelnut", "5.59");
        s.save(hazelnut);
 
        Order order = new Order();
        order.addLine(chestnut, 20);
        order.addLine(hazelnut, 150);
 
        repo.saveOrder(order);
        s.flush();
 
        Order persistent = (Order) s.createCriteria(Order.class).uniqueResult();
        Assert.assertNotSame(0, persistent.getId());
        Assert.assertEquals(new OrderLine(chestnut, 20), persistent
                .getOrderLines().get(0));
        Assert.assertEquals(new OrderLine(hazelnut, 150), persistent
                .getOrderLines().get(1));
    }
}

Здесь стоит отметить несколько деталей:

  1. Я пометил тест @Transactional , чтобы получить прямой доступ к @Transactional . В этом сценарии @EnableTransactionManagement в @Configuration похоже, не имеет никакого эффекта, так как тест все равно будет @Configuration в транзакцию.
  2. Если тест не помечен как @Transactional (имеет @Transactional когда он использует @Transactional компоненты @Transactional ), транзакция, кажется, всегда @TransactionConfiguration независимо от настроек @TransactionConfiguration .
  3. Если тест помечен как @Transactional , @TransactionConfiguration кажется, применяется по умолчанию. Даже если она опущена, транзакция будет @TransactionConfiguration(defaultRollback=false) в конце теста, и если вы хотите, чтобы она была зафиксирована, вам потребуется @TransactionConfiguration(defaultRollback=false) .
  4. Это, вероятно, само собой разумеется, но @Configuration для тестов, вероятно, отличается от производства. Здесь он использует встроенную базу данных H2, для реального применения я бы использовал тестовую базу данных на том же движке, что и рабочая.

Вот и все, только эти два класса Java. Нет XML или искаженных зависимостей. Взгляните на мой репозиторий GitHub для полного кода.

Ссылка: Тестирование Spring и Hibernate без XML от нашего партнера JCG Конрада Гаруса в блоге Белки .