2012-10-26 146 views
4

我首先沒有提到這個問題的關鍵組成部分:我在這裏使用TestNG。Spring + TestNG集成測試,注入帶註釋的DAO失敗

我有一個執行持久性的DAO層。它作爲我的小型Web應用程序的一部分工作正常(我有一個經典的控制器,服務,DAO層設計)。如果需要,我可以用我的XML更新這個問題。

我的服務層

@Service 
public class UserServiceImpl implements UserService { 

    @Autowired 
    private UserDao userDao; 

    @Override 
    public GoodVibeUserDetails getUser(String username) throws UsernameNotFoundException { 

     GoodVibeUserDetails user = userDao.getDetailsRolesAndImagesForUser(username); 

     return user; 
    } 

    // more methods... 

} 

我DAO層

@Repository 
public class UserDaoImplHibernate implements UserDao { 

    @Autowired 
    private SessionFactory sessionFactory; 

    // My methods using sessionFactory & "talking" to the Db via the sessionFactory 
} 

這裏是我的測試類

@Component 
public class UserDaoImplHibernateTests{ 

    @Autowired 
    private UserDao userDao; 

    private GoodVibeUserDetails user; 

    @BeforeMethod 
    public void beforeEachMethod() throws ParseException{ 
     user = new GoodVibeUserDetails(); 
     user.setUsername("adrien"); 
     user.setActive(true); 
     // & so on... 
    } 

    /* 
    * When everything is fine - test cases 
    */ 
    @Test 
    public void shouldAcceptRegistrationAndReturnUserWithId() throws Exception{ 
     assertNotNull(userDao) ; 
     user = userDao.registerUser(user); 
     assertNotNull(user.getId()) ; 
    } 

    // more test cases... 

} 

但我的測試類的自動裝配,userDao總是返回,我只是開始在春季做測試,我有點失落。任何指針都是受歡迎的。


鮑里斯Treukhov的回答後

最新編輯

import ... 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.testng.annotations.BeforeMethod; 
import org.testng.annotations.Test; 
import static org.junit.Assert.assertNotNull; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("/applicationContext.xml") 
public class UserDaoImplHibernateTests{ 

    @Autowired 
    @Qualifier("userDao") 
    private UserDao userDao; 

    private GoodVibeUserDetails user; 

    @BeforeMethod 
    public void beforeEachMethod() throws ParseException{ 
     user = new GoodVibeUserDetails(); 
     user.setUsername("adrien"); 
     user.setActive(true); 
     // & so on... 
    } 

    /* 
    * When everything is fine - test cases 
    */ 
    @Test 
    public void shouldAcceptRegistrationAndReturnUserWithId() throws Exception{ 
     assertNotNull(userDao) ; 
     user = userDao.registerUser(user); 
     assertNotNull(user.getId()) ; 
    } 

    // more test methods... 

} 

這是我的applicationContext.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" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > 


    <!-- the application context definition scans within the base package of the application --> 
    <!-- for @Components, @Controller, @Service, @Configuration, etc. --> 
    <context:annotation-config /> 
    <context:component-scan base-package="com.goodvibes" /> 

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="/WEB-INF/jdbc.properties" /> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" 
     p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.databaseurl}" 
     p:username="${jdbc.username}" p:password="${jdbc.password}" /> 


    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="configLocation"> 
      <value>classpath:hibernate.cfg.xml</value> 
     </property> 
     <property name="configurationClass"> 
      <value>org.hibernate.cfg.AnnotationConfiguration</value> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${jdbc.dialect}</prop> 
       <prop key="hibernate.show_sql">${jdbc.show_sql}</prop> 
       <prop key="hibernate.connection.SetBigStringTryClob">true</prop> 
       <prop key="hibernate.jdbc.batch_size">0</prop> 
      </props> 
     </property> 
    </bean> 

    <tx:annotation-driven /> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    [...] 

</beans> 

我沒有添加存儲庫-config.xml文件,因爲這應該是足以訪問userDao。不過,我仍然得到userDao相等的值。

在此先感謝

回答

11

如果你創建單元測試,Spring IoC來的功能不可用(因爲它是由框架設計師意),因爲你是在隔離測試你的對象(即你正在嘲笑只有很少的集測試完成所需的接口)。在這種情況下,你應該手動注入你的模擬庫,例如@Before測試初始化​​方法。整個想法是你的類只依賴於接口,所以Spring容器基本上評估哪個類用作接口實現,但是當你創建一個單元測試時,你需要嚴格控制哪些接口方法被調用(並且有一個最小的一組依賴性),這就是您手動執行注入的原因。

如果您正在進行集成測試,則應該啓動並運行Spring IoC容器實例,爲此,您應該使用jUnit(假設您使用jUnit)特定的測試運行器,如Spring documentation on testing中所述。

所以,回到問題,你看起來像一個簡單的單元測試jUnit,並沒有使用Spring容器。所以,如果你打算使用Spring TestContext框架,你應該有類似

@RunWith(SpringJUnit4ClassRunner.class) 
    @ContextConfiguration(locations={"/path-to-app-config.xml", "/your-test-specific-config.xml"}) 
    public class UserDaoImplHibernateTests 

,而不是@Component

更新 TestNG中的情況下,我覺得應該是(我以前Spring Dependency Injection with TestNG作爲參考)

@ContextConfiguration(locations={"/path-to-app-config.xml", "/your-test-specific-config.xml"}) 
    public class UserDaoImplHibernateTests extends AbstractTestNGSpringContextTests 

參見:What is the difference between integration and unit tests?

+0

感謝鮑里斯,你明確指出我到正確的方向。我仍然得到userDao相等null雖然。我根據你的回答更新了我的問題。我明顯錯過了一些東西。 –

+0

@AdrienBe移除'@Qualifier(「userDao」)'因爲您沒有在'@ Repository'中指定名稱UserDaoImplHibernate的註釋假設它是userDaoImplHibernate(但我不記得確切的:-),無論如何使用name這裏絕對不需要限定符。 –

+0

沒有運氣,仍然得到userDao等於null –