上一篇文章讲述了如何使用springboot远程的@springBootTest注解实现 hibernate的单元测试。好处上一篇文章已经说了(两点:1、使用application-test.yaml搞定一切; 2、两个注解实现一切初始化功能)。但是有好处也有坏处,坏处就是太重量级了,springboot程序小速度还可以,但是一旦springboot程序庞大了,要是你测试一个小小的函数,就不得不喝一杯茶,等 @springbootTest把所有的springboot程序加载一遍。这中间的时间足够你喝两杯茶了
于是这里有另外一种方法来实现大型springboot的entity bean的单元测试:就是自己手动实现上面所有springboot替你实现的步骤,这样你可以非常轻便的完成JPA 的单元测试
项目代码见 github
见springboot+liquibase+hibernate
其实这个东西可有可以了现在 见Is persistence.xml requied when working with Spring and Hibernate?
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="test-hibernate-local" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="hibernate.cache.use_second_level_cache" value="false"/>
</properties>
</persistence-unit>
</persistence>
类中需要自己指定:
package com.hibernate.springtest;
import liquibase.integration.spring.SpringLiquibase;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* @author wanli zhou
* @created 2017-10-09 2:11 PM.
*/
@Configurable
@EnableTransactionManagement
public class H2DsConfi {
@Bean
public SpringLiquibase springLiquibase(){
SpringLiquibase ln = new SpringLiquibase();
ln.setDataSource(localDataSource());
ln.setChangeLog("classpath:db/changelog/master.xml");
return ln;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(localDataSource());
//https://stackoverflow.com/questions/4736301/is-persistence-xml-requied-when-working-with-spring-and-hibernate
bean.setPersistenceXmlLocation("classpath*:META-INF/persistence-local.xml");
bean.setPersistenceUnitName("test-hibernate-local");
bean.setPackagesToScan("com.hibernate.demo.domain");
bean.setPersistenceProviderClass(org.hibernate.ejb.HibernatePersistence.class);
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(true);
bean.setJpaVendorAdapter(adapter);
return bean;
}
@Bean
public DataSource localDataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
ds.setDriverClassName("org.h2.Driver");
return ds;
}
@Bean
public PlatformTransactionManager localTransactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
txManager.setDataSource(localDataSource());
return txManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslator() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
这里我们用的是spring 原生的单元测试类,同时显示设置了springcontext的配置类 @ContextConfiguration(classes = H2DsConfi.class)
package com.hibernate.springtest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hibernate.demo.domain.City;
import com.hibernate.demo.domain.Province;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
/**
* @author wanli zhou
* @created 2017-10-09 2:23 PM.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = H2DsConfi.class)
public class UseSpringTest {
@PersistenceContext
private EntityManager em;
@Transactional
@Test
public void createCSTest(){
List<City> citis = new ArrayList<>();
City c = new City();
c.setCode("c-tc");
c.setName("test-city");
citis.add(c);
Province newP = new Province();
newP.setName("test-name");
newP.setCode("p-tc");
newP.setCities(citis);
c.setProvince(newP);
em.persist(newP);
em.flush();
List<Province> ps = em.createQuery("select p from Province p where p.name like :name", Province.class)
.setParameter("name", "%test%")
.getResultList();
ObjectMapper objectMapper = new ObjectMapper();
StringWriter stringEmp = new StringWriter();
try {
objectMapper.writeValue(stringEmp, ps);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Employee JSON is\n"+stringEmp);
System.out.println("==");
}
}