我是Spring和JPA的新手。我使用Spring4,spring scheduler和JPA开发了一个项目,现在我想使用Junit测试用例来测试我的代码。我开始测试我的DAO方法。这是源代码:
此类执行调度程序的触发任务
public class TriggerTask {
@Autowired
private TriggerDaoBean triggerDaoBean;
public void executeDailyTask() {
try{
List<User> users=triggerDaoBean.getClients();
if (null != users && users.size()>0){
//do some task
}
}catch(Exception e){
}
}}
DAO bean是:
@Stateless
public class TriggerDaoBean implements Serializable {
private static final long serialVersionUID = 1L;
@PersistenceContext
private EntityManager em;
public List<User> getUsers() {
List<User> userList = new ArrayList<User>();
Query query = em.createQuery(
"SELECT user FROM USER user");
userList = (List<User>)query.getResultList();
if (null != userList && userList.size() > 0) {
return userList;
} else {
return null;
}
}
....
}
我写了下面的测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/spring-quartz-test.xml" })
@TransactionConfiguration(defaultRollback=true)
@Transactional
public class TriggerTest {
@Autowired
TriggerDaoBean triggerDaoBean;
@Test
public void getUserListTest() {
triggerDaoBean.getUsers();
}
}
spring-quartz-test.xml的内容如下:
<bean id="triggerTask" class="com.test.service.TriggerTask">
<property name="triggerDaoBean" ref="triggerDaoBean"/>
</bean>
<bean id="triggerDaoBean"
class="com.test.service.TriggerDaoBean">
</bean>
<bean id="runsrJobDaily" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="triggerTask" />
<property name="targetMethod" value="executeDailyTask" />
</bean>
persistence.xml如下:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="forge-default" transaction-type="JTA" >
<description>Forge Persistence Unit</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>com.test.persistence.entity.User</class>
<properties>
<!-- <property name="hibernate.hbm2ddl.auto" value="create-drop"/> -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<!--
<property name="hibernate.ejb.cfgfile" value="modified.hibernate.cfg.xml"/>
-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.transaction.flush_before_completion" value="true"/>
</properties>
</persistence-unit>
</persistence>
java:/MySqlDS
是数据源的JNDI名称。
每次我运行我的测试时,NullPointerException都会出现在EntityManager中。
我做错了吗?
答案 0 :(得分:1)
我是我的情况,您需要在测试类上添加两个注释。
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootApplicationClass.class)
答案 1 :(得分:0)
你必须在spring中定义你的entityManager,我在你发布的代码中看不到entityManager,你可以这样做吗
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="example" />
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
请注意,您在persistence.xml中将事务类型定义为JTA,您真的需要全局事务吗?如果没有,请删除persistence.xml中的transaction-type="JTA"
另一方面,出于测试目的,最好使用像H2这样的测试数据库。您可以在src/test/resources
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence-test.xml"/>
<property name="persistenceUnitName" value="example-test" />
<property name="dataSource" ref="dataSourceTest"/>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="dataSourceTest" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
factory-method="createWebServer" init-method="start" lazy-init="true">
<constructor-arg value="-web,-webAllowOthers,-webPort,11111" />
</bean>
这样你可以控制数据库状态,每个测试都会在内存中创建一个数据库,你可以在import.sql
中定义一个src/test/resource
,以便用测试数据填充你的表。您必须在pom.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.174</version>
<scope>test</scope>
</dependency>