2016-08-30 6 views
1

У меня есть единичный тест, который включает в себя несколько простых операций с базой данных. Взаимодействие с базой данных осуществляется с помощью Spring Data и JPA. Моя среда - Spring Boot 1.4.Загрузка только Spring Boot Data/JPA-уровня в тесте Unit/Integration с базой данных

Мой тест выглядит следующим образом:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 
@SpringBootTest(classes = {Application.class}) 
@Transactional 
public class OrderRepositoryTest { 
    @Autowired 
    private OrderRepository orderRepository; 

    @Autowired 
    EntityManager entityManager; 

    @Test 
    public void can_create_and_find_one_order() { 
     String orderId = "XX_YY"; 

     Order order1 = createAnOrder(); 
     orderRepository.save(order1); 

     entityManager.flush(); 
     entityManager.clear(); 

     Order order2 = orderRepository.findOne(orderId); 
     Assertions.assertThat(order2).isEqualTo(order1); 
    } 
} 

Где Применение является точкой входа Spring загрузки, и содержит EnableAutoConfiguration аннотацию:

@EnableAutoConfiguration 
@EnableConfigurationProperties 
@ComponentScan(basePackageClasses = { 
    WebMvcConfig.class, 
    ServicesConfiguration.class, 
    WebSecurityConfiguration.class 
}) 
public class Application extends SpringBootServletInitializer { 
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) { 
     return applicationBuilder.sources(Application .class); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Теста ли загрузить слой JPA, и выполняет операцию. Но он также загружает конфигурацию MVC, конфигурацию безопасности и множество других слоев, которые я не тестирую.

Вопрос: Как я могу заменить EnableAutoConfiguration и загрузить только тот слой JPA, который мне нужен?

В идеале было бы класс конфигурации похож на расширение'WebMvcConfigurerAdapter' таким образом, что я могу использовать его из модульного тестирования и точки входа в приложение, так что мой блок тест также проверяет конфигурацию:

@Configuration 
@EnableJpaRepositories(basePackages = "class.path.to.my.repositories") 
public class PersistenceConfiguration { 
    // Whatever needs to be here 
    // ... 
} 

ответ

2

Если вы просто хотите протестировать уровень JPA, вам понадобится только @DataJpaTest, он настроит встроенную базу данных в памяти, сканирует классы @Entity и настроит репозитории Spring Data JPA. Регулярные компоненты @Component не будут загружаться в ApplicationContext.

Например:

@RunWith(SpringRunner.class) 
@DataJpaTest 
@Transactional 
public class SpringBootJPATest { 

    @Autowired 
    private BlogEntryRepository blogEntryRepository; 

    @Autowired 
    private TestEntityManager entityManager; 

    @Test 
    public void jpa_test() { 
     BlogEntry entity = new BlogEntry(); 
     entity.setTitle("Test Spring Boot JPA Test"); 
     BlogEntry persist = entityManager.persist(entity); 
     System.out.println(persist.getId()); 
    } 

    @Test 
    public void jap_test_repo() { 
     BlogEntry entity = new BlogEntry(); 
     entity.setTitle("Test Spring Boot JPA Test"); 
     BlogEntry persist = blogEntryRepository.save(entity); 
     System.out.println(persist.getId()); 
    } 
} 

BlogEntryRepository просто пустой интерфейс, который расширяет JpaRepository

Выход (я удалил другой информации журнала просто оставить все журналы Hibernate):

Hibernate: drop table blog_entry if exists 
Hibernate: drop table comment if exists 
Hibernate: create table blog_entry (id bigint generated by default as identity, content varchar(255), created_on timestamp, title varchar(255), updated_on timestamp, primary key (id)) 
Hibernate: create table comment (id bigint generated by default as identity, comment varchar(255), blog_entry_id bigint, primary key (id)) 
Hibernate: alter table comment add constraint FK5f23qjwyt0ffjboqu3go58buu foreign key (blog_entry_id) references blog_entry 

...... 

Hibernate: insert into blog_entry (id, content, created_on, title, updated_on) values (null, ?, ?, ?, ?) 
1 

...... 

Hibernate: drop table blog_entry if exists 
Hibernate: drop table comment if exists 
+0

Поскольку исходный плакат, по-видимому, хочет провести транзакционные тесты, вы должны удалить '(распространение = распространение_NOT_SUPPORTED)' (и переименовать тестовый класс). В противном случае ваш ответ выглядит хорошо. –

+0

@SamBrannen да, спасибо за напоминание. –

+0

Если я просто использую этот код без каких-либо изменений, я получаю ошибку 'Невозможно найти @SpringBootConfiguration, вам нужно использовать @ContextConfiguration или @SpringBootTest (classes = ...) с вашим тестом' – jmgonet

2

As spring-boot document упомянутый, использование @DataJpaTest - сбор способ. Попробуйте под кодом, это работает для меня.

@RunWith(SpringRunner.class) 
@Import(PersistenceConfiguration.class) 
@ContextConfiguration(classes = YourOrderRepositoryImpl.class) 
@DataJpaTest 
@Transactional 
public class OrderRepositoryTest { 
    @Autowired 
    private OrderRepository orderRepository; 

    @Autowired 
    TestEntityManager entityManager; 

    @Test 
    public void foo() { 
    ... 
    } 
} 

Использование @DataJpaTest также необходимо использовать @ContextConfiguration в конфиг в аренду одну пружину в управлении-боб, в противном случае вы получите сообщение об ошибке Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test.

И вы можете использовать TestEntityManager вместо EntityManager. Это также документ there.