2016-12-08 49 views
0

我想寫我的DAO類的JUnit測試的Java Spring MVC和我得到的錯誤實現類如下:單元測試:當在Eclipse中運行下面的測試使用Hibernate和H2數據庫

package com.bookstore.dao; 
import org.hibernate.Query; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 
import java.util.List; 
import com.bookstore.domain.Book; 
import com.bookstore.exception.BookNotFoundException; 

@Repository 
@Transactional 
public class BookDaoImpl implements BookDao { 

    @Autowired 
    private SessionFactory sessionFactory; 
    private Session session = null; 

    public List<Book> getAllBooks() { 
     session = sessionFactory.getCurrentSession(); 
     Query query = session.createQuery("FROM Book"); 
     List<Book> books = query.list(); 
     session.flush(); 
     return books; 
    } 

    public Book getBookById(int bookId) { 
     session = sessionFactory.getCurrentSession(); 
     Book bookById = (Book) session.get(Book.class, bookId); 
     session.flush(); 
     if (bookById == null) { 
      throw new BookNotFoundException(bookId); 
     } 
     return bookById; 
    } 

    public void bookInsert(Book book) { 
     session = sessionFactory.getCurrentSession(); 
     session.saveOrUpdate(book); 
     session.flush(); 
    } 

    // more methods here (not relevant for the question) 
} 

我也創建的applicationContext-的test.xml文件夾下的src /測試/資源如下:

<?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"> 
    <bean id="dataSource" 
     class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="org.h2.Driver" /> 
     <property name="url" value="jdbc:h2:tcp://localhost/~/test" /> 
     <property name="username" value="sa" /> 
     <property name="password" value="" /> 
    </bean> 
    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.Dialect"> 
        org.hibernate.dialect.H2Dialect</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
       <prop key="hibernate.show_sql">false</prop> 
       <prop key="hibernate.format_sql">true</prop> 
      </props> 
     </property> 
     <property name="packagesToScan"> 
      <list><value>com.bookstore</value></list> 
     </property> 
    </bean> 
    <bean id="transactionManager" 
     class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 
</beans> 

現在我在JUnit窗口得到的錯誤是NullPointerException在我的測試中bookDao.bookInsert(book);行:

JUnit window of Eclipse

並在控制檯中,我可以看到以下內容:

INFO: HHH000232: Schema update complete 
Dec 08, 2016 10:16:41 PM org.springframework.orm.hibernate4.HibernateTransactionManager afterPropertiesSet 
INFO: Using DataSource [[email protected]9fee] of Hibernate SessionFactory for HibernateTransactionManager 
Dec 08, 2016 10:16:41 PM org.springframework.context.support.GenericApplicationContext doClose 
INFO: Closing [email protected]fcfece: startup date [Thu Dec 08 22:16:38 GMT 2016]; root of context hierarchy 
+0

使會話成爲實例變量是一個錯誤,線程可以訪問會話或同時覆蓋對它的引用。 –

+0

嘗試添加'@ Autowired' for'bookDao' – Jerry06

+0

Nathan,你的意思是我應該在每個方法中使用'Session session = sessionFactory.getCurrentSession();'而不是實例變量'private Session session = null;'? – Dubliner

回答

0

可能是您的applicationContext.xml文件不在您的單元測試的類路徑中。嘗試將其複製到測試包的資源文件夾中。

或者您已經在@Before setup方法中自己創建了dao,爲什麼還要使用@Autowired?

+0

我在文件夾src/test/resources下創建了另一個文件 - applicationContext-test.xml,並刪除了@Autowired註釋。看起來測試試圖運行,但仍然有錯誤。當我放聲 - 空指針在我的BookDaoImpl類的'session = sessionFactory.getCurrentSession();'行被拋出。 – Dubliner

+0

你如何配置你的會話工廠?如果它在xml文件中,它也可能從類路徑中丟失 – Reek

+0

會話工廠在文件'src/test/resources'下的'applicatioContext-test.xml'文件中配置 – Dubliner

0

我認爲問題在於您在BookDaoImplTest中創建BookDao實例的方式。 BookDao和它內部的引用bean被正確創建的唯一方法是通過依賴注入(例如使用@Autowired)。如果通過使用「new」運算符或嘲笑它手動創建它,像「sessionFactory」這樣的字段可能爲空(如果不手動設置它們)。

+0

如果我將'@ Autowired'添加到'BookDao bookDao;'我會得到錯誤:'SEVERE:抓住異常,同時允許TestExecutionListener [org.springframewor[email protected]64616ca2]準備測試實例[[email protected]] org.springframework.beans.factory.UnsatisfiedDependencyException:創建名爲'com.bookstore.dao.BookDaoImplTest'的bean時出錯:通過字段'bookDao'表示的不滿足的依賴關係;嵌套的異常是org.springframework.beans.factory.NoSuchBeanDefinitionException:沒有找到符合條件的bean ...' – Dubliner

+0

所以它意味着spring無法找到您的applicationContext-test.xml。在您的BookDaoImplTest中,您可以嘗試用@ContextConfiguration(locations = {「classpath:applicationContext-test.xml」})替換'@ContextConfiguration(locations = {「classpath:**/applicationContext-test.xml」})') ' –

相關問題