напоминание
- Test Fixture — фиксированное состояние, используемое в качестве основы для выполнения тестов.
- Модульный тест — эти тесты проверяют, что части кода (компоненты) выполняют некоторые функции, как ожидалось. В среде Java они обычно реализуются на уровне класса.
- Интеграционный тест — Интеграционный тест — это любой тип теста, который проверяет, что набор взаимодействующих компонентов правильно выполняет ожидаемые функции.
конфигурация
Нам нужна конфигурация JPA Hibernate для тестирования в памяти:
|
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
@Configuration@EnableTransactionManagementpublic class JpaTestConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){ LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean(); lcemfb.setDataSource(this.dataSource()); lcemfb.setPackagesToScan(new String[] {'com.jverstry'}); lcemfb.setPersistenceUnitName('MyTestPU'); HibernateJpaVendorAdapter va = new HibernateJpaVendorAdapter(); lcemfb.setJpaVendorAdapter(va); Properties ps = new Properties(); ps.put('hibernate.dialect', 'org.hibernate.dialect.HSQLDialect'); ps.put('hibernate.hbm2ddl.auto', 'create'); lcemfb.setJpaProperties(ps); lcemfb.afterPropertiesSet(); return lcemfb; } @Bean public DataSource dataSource(){ DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName('org.hsqldb.jdbcDriver'); ds.setUrl('jdbc:hsqldb:mem:testdb'); ds.setUsername('sa'); ds.setPassword(''); return ds; } @Bean public PlatformTransactionManager transactionManager(){ JpaTransactionManager tm = new JpaTransactionManager(); tm.setEntityManagerFactory( this.entityManagerFactoryBean().getObject() ); return tm; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){ return new PersistenceExceptionTranslationPostProcessor(); }} |
Нам нужно исключить рабочую конфигурацию из сканирования пакетов (без сканирования com.jverstry):
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
@Configuration@ComponentScan(basePackages = { 'com.jverstry.Controller', 'com.jverstry.DAO', 'com.jverstry.Item', 'com.jverstry.Service'})public class TestConfig { @Bean public MyService getMyService() { return new MyServiceImpl(); }} |
Инструменты весеннего тестирования
- @RunWith — это аннотация JUnit, позволяющая запустить тест с другим бегуном, чем тот, который предоставляется JUnit.
- SpringJUnit4ClassRunner — это бегущий тест JUnit для приложений Spring. Как правило, тестовые классы обозначаются с помощью @RunWith (SpringJUnit4ClassRunner.class).
- @ContextConfiguration — эта аннотация может использоваться, чтобы указать, как загрузить applicationContext в тестовом классе Spring. Это можно настроить с помощью файлов XML или объектов конфигурации Java.
Сервисное тестирование
Следующий класс тестирует метод createAndRetrieve () нашей внедренной реализации MyService:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes={ JpaTestConfig.class, TestConfig.class })public class MyServiceImplTest { @Autowired private MyService myService; @Test public void testCreateAndRetrieve() { MilliTimeItem retr = myService.createAndRetrieve(); assertNotNull(retr); }} |
DAO Testing
Следующий класс тестирует нашу реализацию DAO. Наша реализация внедряется с EntityManager, созданным из нашего тестового класса конфигурации, определенного выше.
|
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
|
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes={ JpaTestConfig.class, TestConfig.class })public class MyPersistenceDAOTest { @Autowired private MyPersistenceDAO myDAO; @Test public void testCreateMilliTimeItem() { // This operation should not throw an Exception long id = myDAO.createMilliTimeItem(); } @Test public void testGetMilliTimeItem() { long id = myDAO.createMilliTimeItem(); MilliTimeItem retr = myDAO.getMilliTimeItem(id); assertNotNull(retr); assertEquals(id,retr.getID()); }} |
Предостережение
Начиная писать тесты JUnit для Spring, можно встретить следующие сообщения об ошибках:
|
1
2
|
Java.lang.ClassFormatError:Absent Code attribute in method that is not native or abstract in class file javax/validation/Validation |
Вышесказанное часто вызвано следующей зависимостью maven:
|
1
2
3
4
5
6
|
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0</version> <type>jar</type></dependency> |
Следует заменить на:
|
1
2
3
4
5
6
|
<dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jpa_2.0_spec</artifactId> <version>1.1</version> <scope>provided</scope></dependency> |
Другое сообщение об ошибке:
|
1
|
javax.validation.ValidationException: Unable to find a default provider |
Это решается добавлением следующей зависимости maven:
|
1
2
3
4
5
|
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.3.0.Final</version></dependency> |
Больше Spring связанных постов здесь .
Ссылка: JUnit Testing Spring Service и DAO (с базой данных в памяти) от нашего партнера JCG Джерома Версринга в блоге технических заметок .