2015-09-04 53 views
1

我有AuthorJDBCDAO类,它具有扩展AbstractJDBCDAO类并实现AuthorDAO接口的基本CRUD方法。 我通过psv main() method测试了所有方法,一切都很好。 但现在我必须使用DBUnit测试它的方法。在这里,我的麻烦开始了。 我尝试只测试create()方法,它不能正常工作。 我使用Unitils,Spring DI,Oracle DB来创建我的应用程序。 我向bean AuthorJDBCDAO注入bean DataSource(dbcp2)。我使用XML配置注入bean。 这是我的源代码和配置文件。 测试类。由DBUnit测试JdbcDao的问题

@SpringApplicationContext({"spring-test-config.xml"}) 
@DataSet(value = "AuthorDAOTest.xml", loadStrategy =  CleanInsertLoadStrategy.class) 
public class AuthorDAOTest extends UnitilsJUnit4 { 

@SpringBean("authorJDBCDAO") 
private AuthorJDBCDAO authorDAO; 

@Test 
public void testCreate() throws DAOException { 
    Author expected = new Author(); 
    expected.setName("BLABLABLA"); 
    expected.setExpiredDate(Timestamp.valueOf(LocalDateTime.now())); 
    Author result = null; 


    result = authorDAO.create(expected); 

    assertEquals(expected.getId(), result.getId()); 
    System.out.println("Hello from test"); 
} 

这里是执行Test类的堆栈跟踪。

newsportal.exception.DAOException: java.sql.SQLException: Connection is null. 
at newsportal.dao.impl.AbstractJDBCDAO.create(AbstractJDBCDAO.java:115) 
at com.epam.ivanou.newsportal.dao.impl.AuthorJDBCDAOTest.testCreate(AuthorJDBCDAOTest.java:33) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) 
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:108) 
at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runTestMethod(UnitilsJUnit4TestClassRunner.java:204) 
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89) 
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97) 
at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:186) 
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 
at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95) 
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:59) 
at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:42) 
at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:60) 
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 
at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:67) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
Caused by: java.sql.SQLException: Connection is null. 
at org.apache.commons.dbcp2.DelegatingConnection.checkOpen(DelegatingConnection.java:608) 
at org.apache.commons.dbcp2.DelegatingConnection.prepareStatement(DelegatingConnection.java:286) 
at com.epam.ivanou.newsportal.dao.impl.AbstractJDBCDAO.create(AbstractJDBCDAO.java:106) 
... 29 more 

AbstractJDBCDAO类的代码片段。我得到这个例外。我试图调试它,发现在第二次try-catch-with-resources块连接中是空的。但我不明白,如果我尝试从BasicDataSource的DataSource获取连接并支持连接池,会发生什么情况。

@Override 
public T create(T object) throws DAOException { 
    T persistInstance; 
    // Add the record 
    String sql = getCreateQuery(); 
    String idName = getIdString(); 
    String tableName = getTableName(); 

    try (Connection connection = DataSourceUtils.getConnection(dataSource); 
     PreparedStatement statement = connection.prepareStatement(sql)) { 
     System.out.println("connection: "+ connection + " data source: " + dataSource); 
     prepareStatementForInsert(statement, object); 
     int count = statement.executeUpdate(); 
     if (count != 1) { 
      throw new DAOException("On persist modify more then 1 record: " + count); 
     } 
    } catch (Exception e) { 
     throw new DAOException(e); 
    } 
    // Get recently inserted record 
    sql = getSelectQuery() + " WHERE " + idName + " = (SELECT MAX(" + idName + ") FROM " 
      + tableName + ")"; 


    try (Connection connection = DataSourceUtils.getConnection(dataSource); 
     PreparedStatement statement = connection.prepareStatement(sql)) //here is connection is null and SQLException is thrown { 
     System.out.println("connection: "+ connection + " data source: " + dataSource); //TODO connection is null in test method, but is good when using main() method 
     ResultSet rs = statement.executeQuery(); 
     List<T> list = parseResultSet(rs); 
     if ((list == null) || (list.size() != 1)) { 
      throw new DAOException("Exception on findByPK new persist data."); 
     } 
     persistInstance = list.iterator().next(); 
    } catch (Exception e) { 
     throw new DAOException(e); 
    } 
    return persistInstance; 
} 

我豆类我这里还有配置文件: 道的beans.xml

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> 

    <bean id="authorJDBCDAO" class="newsportal.dao.impl.AuthorJDBCDAO"> 
      <constructor-arg ref="dataSource"/> 
    </bean> 

数据库测试-config.xml中

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> 


<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location"> 
     <value>db_test.properties</value> 
    </property> 
</bean> 

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driverClassName}"/> 
    <property name="url" value="${jdbc.url}"/> 
    <property name="username" value="${jdbc.username}"/> 
    <property name="password" value="${jdbc.password}"/> 
    <property name="maxIdle" value="${jdbc.maxIdle}"/> 
    <property name="minIdle" value="${jdbc.minIdle}"/> 
    <property name="maxWaitMillis" value="${jdbc.maxWaitMillis}"/> 
    <property name="initialSize" value="${jdbc.initialSize}"/> 
</bean> 

<bean id="transactionManager" 
     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 


</beans> 

弹簧test-config.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd"> 


<import resource="database-test-config.xml" /> 
<import resource="dao-beans.xml" /> 

</beans> 

db_test.properties

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver 
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe 
jdbc.username=Yahor_test 
jdbc.password=1234 
jdbc.maxIdle=100 
jdbc.minIdle=10 
jdbc.maxWaitMillis=10000 
jdbc.initialSize=10 

和这里的测试简单的Java类:

public class Test { 
    public static void main(String[] args) throws DAOException { 
    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml"); 
    AuthorJDBCDAO authorDAO = (AuthorJDBCDAO) ctx.getBean("authorJDBCDAO"); 

     Author author = new Author(); 
     author.setName("Yahor"); 
     author = authorDAO.create(author); 
     System.out.println(author.getId()); 

    } 

而且它的正常工作=) 可能不便错在我DBUnit的测试类事务的配置?

+0

我在调试调试变量,并发现,在第二次try-catch-with-resources中我关闭了连接。 –

回答

0

问题解决了。我应该通过DataSourceUtils.doReleaseConnection()关闭连接。否则连接将在物理上关闭。这是我麻烦的关键。