Spring Data JPA. JUnit тесты для Services. Часть 3

В этом уроке мы напишем интеграционые тесты для проверки наших сервисов с помощью JUnit. Довольно часто это требуется чтобы протестировать Service слой, именно это мы и будем делать.

О том что такое JUnit и для чего он можно почитать тут.

Ранее уже публиковались уроки:

Spring Data JPA. Работа с БД. Часть 1

Spring Data JPA. Пишем DAO и Services. Часть 2

этот урок является продолжением серии.

 

Тестировать мы будем только сервис BankService так как остальные тестируется сервисы тестируются аналогичным способом.

Также целью этого урока не является как можно правильней и лучше протестировать данный сервис, а то, как проверить работоспособность сервиса и сконфигурировать Spring Context для тестирования Spring компонентов.

 

Шаг 0. Зависимости

Обратите внимание, что в первой части этой серии мы подключали две зависимости:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.test}</version>
    <scope>test</scope>
</dependency>

Первая зависимость это JUnit Framework для тестирования, вторая это поддержка Spring для тестирования.

 

Шаг 1. Конфигурирование Spring

Теперь нам нужно сконфигурировать Spring для тестов это можно сделать испоьзуя туже конфигурацию что и в первом уроке.

Разница между нимим будет только в том что DataSource будет сконфигурирован под тестовую БД — testdb.

package com.devcolibri.dataexam.test.config;

import org.hibernate.ejb.HibernatePersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@ComponentScan("com.devcolibri.dataexam")
public class TestDataBaseConfig {

    private static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver";
    private static final String PROPERTY_NAME_DATABASE_URL = "jdbc:mysql://localhost:3306/testdb";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "root";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "root";

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "org.hibernate.dialect.MySQLDialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "true";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "com.devcolibri.dataexam.entity";
    private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "create-drop";

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
        entityManagerFactoryBean.setPackagesToScan(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN);

        entityManagerFactoryBean.setJpaProperties(hibernateProp());

        return entityManagerFactoryBean;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

        return transactionManager;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER);
        dataSource.setUrl(PROPERTY_NAME_DATABASE_URL);
        dataSource.setUsername(PROPERTY_NAME_DATABASE_USERNAME);
        dataSource.setPassword(PROPERTY_NAME_DATABASE_PASSWORD);

        return dataSource;
    }

    private Properties hibernateProp() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect",	PROPERTY_NAME_HIBERNATE_DIALECT);
        properties.put("hibernate.show_sql", PROPERTY_NAME_HIBERNATE_SHOW_SQL);
        properties.put("hibernate.hbm2ddl.auto", PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO);
        return properties;
    }

}

Не будем углубляться в подробности, так как все это было рассмотрено в первой части, мы то же самое модифицировали под нашу тестовую БД. Данная конфигурация будет отвечать за наш контекст и все beans которые мы в нем сконфигурировали, будут созданы после того как контекст запустится.

 

Шаг 2. Создание тестового класса

Давайте создадим тестовый класс со всеми аннотациями и ниже их рассмотрим:

package com.devcolibri.dataexam.test.service;

import com.devcolibri.dataexam.service.BankService;
import com.devcolibri.dataexam.test.config.TestDataBaseConfig;
import com.devcolibri.dataexam.test.util.BankUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

@DirtiesContext
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestDataBaseConfig.class)
@WebAppConfiguration
public class BankServiceTest {

    @Resource
    private EntityManagerFactory emf;
    protected EntityManager em;

    @Resource
    private BankService bankService;

    @Before
    public void setUp() throws Exception {
        em = emf.createEntityManager();
    }

    @Test
    public void testSaveBank() throws Exception {
        bankService.addBank(BankUtil.createBank());
    }
}

Анотации:

@DirtiesContext — говорит что ApplicationContext Spring будет связан с тестовым классом;

@RunWith(SpringJUnit4ClassRunner.class) — говорит JUnit-у что для запуска тестов нужно использовать спринговый ранер;

@ContextConfiguration(classes = TestDataBaseConfig.class) — с помощью этой аннотации мы указываем какую конфигурацию контекста использовать, можно указывать несколько. Обратите внимание что мы указали конфигурацию, которую создали в первом шаге.

@WebAppConfiguration — используется для тестирования контроллеров например, чтобы иметь доступ к веб-ресурсам.

 

Для удобства и не обязательно:

Ну и на завершение был создан утильный класс, который бы создавал нужные нам экземпляры объектов:

package com.devcolibri.dataexam.test.util;

import com.devcolibri.dataexam.entity.Bank;

public class BankUtil {

    public static Bank createBank() {
        Bank bank = new Bank();
        bank.setName("Gold Bank");

        return bank;
    }

}

Для закрепления материала можно использовать:

1. Unit тестирование с JUnit

2. Spring Data JPA. Работа с БД. Часть 1

3. Spring Data JPA. Пишем DAO и Services. Часть 2

Урок создан: 24 июля 2014 | Просмотров: 20247 | Автор: Александр Барчук | Правила перепечатки


Добавить комментарий

Добавить комментарий

Ваш e-mail не будет опубликован.

Комментарии:

  • 26 июля 2014 в 15:18

    iVAN

    Выложите проект

  • 06 ноября 2014 в 02:27

    IvanDurov

    Во-первых спасибо.
    Опечатки мелкие в статье есть, вот те что увидел «испоьзуя», «нимим».
    IDEA пишет, что HibernatePersistance устарел — в stackoverflow посоветовали использовать HibernatePersistanceProvider
    http://stackoverflow.com/questions/21871283/spring-data-jpa-java-config-hibernatepersistence-class

    • 06 ноября 2014 в 15:40

      IvanDurov

      Ах, да. Во второй статье нету ссылки на третью [статью](только то, что вы её пишите).

  • 23 февраля 2015 в 12:57

    Yaroslav

    Очень помогает Ваш сайт разобраться со Спрингом. А следующая часть будет? А то я сам пробовал добавтить MVC но что то не вышло его с Spring-Data соеденить. Я так понял какято не совместимость с версиями.

  • 09 сентября 2015 в 20:35

    Константин

    Отлично! Спасибо! Скачал и легко открыл проект в Эклипс и переделал на работу с Постгрес. Начинаю использовать рассмотренные технологии в новом проекте!

  • 09 июня 2016 в 12:46

    Анатолий

    Интересный материал, спасибо. Объясните пожалуйста, при использовании hibernate я объявлял SessionFactory в настройках и добавлял настройки для пулла соединений.
    @Repository(«userDAO»)
    public class UserDAOImpl implements UserDAO {
    @Autowired
    private SessionFactory sessionFactory;

    При использовании SpringData нужно ли объявлять SessionFactory что бы использовать пулл? Я новичок и еще не совсем все понимаю, информации тонна, уже каша в голове.

    • 18 июля 2016 в 23:13

      Андрей

      для пула соединений используй Hikari
      Внимательно прочитай про SpringData. С её использованием, слой дао не нужен.

  • 19 декабря 2016 в 19:50

    Владислав

    Добрый вечер.Я повторил все шаги и ошибок нет, но как теперь запустить, чтобы проверить??

  • 19 декабря 2016 в 19:52

    Владислав

    Добрый вечер. Я повторил шаги и ошибок пока IDEA не нашла, но как запустить это приложение???

    • 19 декабря 2016 в 20:29

      Владислав

      Еще хотел добавить, что хотел выводить результат запроса на web странницу, что нужно сделать???