2009-09-30 73 views
6

使用Spring進行單元測試的最佳實踐方法是什麼?我假設Spring 3的組合TestNG & jmockit不錯,所以這就是我現在正在做的事情,但如果我選擇了新的Spring項目的工具,請立即告訴我。 :-)TestNG和Spring 3

無論如何,我創建了一個我想測試的實體,但我不確定如何從Spring上下文實際運行TestNG。我創建了一個簡單的測試類

package com.mydomain.data.entities.test; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 
import org.testng.Assert; 
import org.testng.annotations.*; 

@ContextConfiguration(locations={"classpath:applicationContext.xml"}) 
public class SimpleTest extends AbstractTestNGSpringContextTests { 

    @Autowired 
    private ApplicationContext applicationContext; 

    @BeforeClass 
    protected void setUp() throws Exception { 
     Assert.assertNotNull(applicationContext); 
    } 

    @Test 
    public void testNothing() { 

    } 

} 

with applicationContext.xml導入用於設置模型和業務層的bean。首先,我希望它使用Project/WebRoot/WEB-INF中的applicationContext.xml,而此測試的源代碼位於Project/src/com/mydomain/data/entities/test中,但我相信/applicationContext.xml會給我Projects/src,和classpath一樣:這是正確的嗎?此外,現在我正在使用我的Web應用程序將使用的模型和業務層,我應該期望它的行爲類似。但是,當我啓動TestNG的在測試中,最高審計機關: 類org.hibernate.cfg.ExtendedMappings具有界面org.hibernate.cfg.Mappings爲超類:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:/Users/niklas/Documents/Eclipse/Project/WebRoot/WEB-INF/Project-Model.xml]: Invocation of init method failed; nested exception is java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1393) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:449) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:289) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:286) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:352) 
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:266) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:121) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:77) 
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70) 
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:99) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1414) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1381) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511) 
    ... 38 more 
Caused by: java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:700) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:319) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:254) 
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:399) 
    at org.hibernate.cfg.AnnotationConfiguration.createExtendedMappings(AnnotationConfiguration.java:187) 
    at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1162) 
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:667) 
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1452) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1390) 
    ... 53 more 

這是什麼東西,爲什麼我收到這個?任何線索?

我SessionFactory的看起來像這樣

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="annotatedClasses"> 
     <list> 
     <!-- Entity classes from package com.mydomain.data.entities --> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
     <prop key="hibernate.show_sql">false</prop> 
     </props> 
    </property> 
    </bean> 
+0

SPring的測試支持用於集成測試,而不是單元測試。您可以使用普通的JUnit或TestNG進行單元測試。那麼你究竟在試圖達到什麼樣的測試? – SteveD 2009-09-30 11:53:01

回答

5

現在的問題似乎並沒有涉及到任何Spring或TestNG。關鍵部分是:

java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 

您確定您的CLASSPATH正常嗎?即你有兼容版本的Hibernate模塊,並且沒有重複?

,如果你創建一個簡單的TestNG的測試,做以下內容:

Class.forName("org.hibernate.cfg.ExtendedMappings"); 

+0

因此,如果我給測試一個空的上下文我可以運行一個包含Class.forName的測試,它給了我:java.lang.IncompatibleClassChangeError:class org.hibernate.cfg.ExtendedMappings將接口org.hibernate.cfg.Mappings作爲超類但是當我運行相同的在我的servlet環境中,我沒有問題。他們有相同的類路徑。 – niklassaers 2009-09-30 13:27:01

+0

我相信在我的任何jar文件中定義的唯一的ExtendedMappings位於hibernate-annotations.jar中。 – niklassaers 2009-09-30 13:28:42

+0

嗯,這可能是因爲我用Hibernate-Annotations 3.4運行Hibernate 3.5-beta1。讓我試試並降級到3.4,看看它們是否更加一致,然後:-) – niklassaers 2009-09-30 13:33:59

1

Spring文檔中請教關於TestNG的一章:爲Spring 2.5

+0

別擔心,我只是在Spring 3參考手冊中閱讀「Spring TestContext Framework」兩次後才寫到這裏,並閱讀了不少教程 – niklassaers 2009-09-30 12:57:57

7

您的測試ckass需要延續AbstractTestNGSpringContextTests。或者,如果您的代碼正在測試數據庫訪問,另一個有用的類可以擴展爲AbstractTransactionalTestNGSpringContextTests

+0

非常感謝。擴展AbstractTestNGSpringContextTests使其加載上下文,但它在初始化時給我一個奇怪的異常。我已經更新了我的問題,但它給我的上下文的例外 – niklassaers 2009-09-30 13:00:32

+0

請原諒這個問題,因爲它是原始問題的答案,並且是我正在尋找的東西(例如:在TestNG中使用Spring) – 2010-12-19 12:01:27

0

您可能想嘗試hibernate-annotations-3.5.0-Beta-1,因爲它與hibernate-core-3.5.0-Beta-1一致。

有時我仍然得到java.lang.IncompatibleClassChangeError,因爲我試圖使用使用「舊」註釋的hibernate搜索。

另外,不知道你是否運行JBoss,但如果你是核心3.5.0會得到這個錯誤。

+0

如果你使用的是hibernate-core-3.5.x,它應該包含註釋(和entityManager) - 根據hibernate不再需要單獨的jar包https://www.hibernate.org/397.html – John 2010-01-14 01:53:12

+0

這就是我認爲,但我仍然需要拉註釋。如果你看看hibernate-annotations pom它有hibernate-core作爲依賴。我認爲冬眠意味着版本號是一致的。或者我喝了太多啤酒:) – 2010-01-16 19:32:31

1

對我來說,這個問題是由於我有不同的休眠版本,而不是因爲包括他們在內的第三方。爲了確保你的服務器只使用一個hibernate版本,你的項目/ poms的一次掃描是值得的。