Я очень заинтересован в улучшениях в 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@EnableTransactionManagementpublic 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 })@Transactionalpublic 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)); }} |
Здесь стоит отметить несколько деталей:
- Я пометил тест
@Transactional, чтобы получить прямой доступ к@Transactional. В этом сценарии@EnableTransactionManagementв@Configurationпохоже, не имеет никакого эффекта, так как тест все равно будет@Configurationв транзакцию. - Если тест не помечен как
@Transactional(имеет@Transactionalкогда он использует@Transactionalкомпоненты@Transactional), транзакция, кажется, всегда@TransactionConfigurationнезависимо от настроек@TransactionConfiguration. - Если тест помечен как
@Transactional,@TransactionConfigurationкажется, применяется по умолчанию. Даже если она опущена, транзакция будет@TransactionConfiguration(defaultRollback=false)в конце теста, и если вы хотите, чтобы она была зафиксирована, вам потребуется@TransactionConfiguration(defaultRollback=false). - Это, вероятно, само собой разумеется, но
@Configurationдля тестов, вероятно, отличается от производства. Здесь он использует встроенную базу данных H2, для реального применения я бы использовал тестовую базу данных на том же движке, что и рабочая.
Вот и все, только эти два класса Java. Нет XML или искаженных зависимостей. Взгляните на мой репозиторий GitHub для полного кода.
Ссылка: Тестирование Spring и Hibernate без XML от нашего партнера JCG Конрада Гаруса в блоге Белки .