2012-07-24 115 views
4

我被困了一段時間了。我搜索了很多,我找不到最簡單的方法來測試實體類或JPA操作對postgres數據庫。我已經找到了如何使用Spring,Mockito和其他的東西,但我找不到使用純Java的最簡單的方法。JUnit,JPA,Hibernate和Postgres:如何測試?

我有以下的JUnit測試:

public class ModelConverterTest { 

    private static EntityManagerFactory emf; 
    private static EntityManager em; 


    public ModelConverterTest() { 
    } 

    @BeforeClass 
    public static void setUpClass() throws Exception { 
     emf = Persistence.createEntityManagerFactory("PU"); 
     em = emf.createEntityManager(); // Retrieve an application managed entity manager 
    } 

    @AfterClass 
    public static void tearDownClass() throws Exception { 
     em.close(); 
     emf.close(); //close at application end 
    } 

    @Before 
    public void setUp() { 
     ...  
    } 

    @After 
    public void tearDown() { 
    } 

    /** 
    * Test of SIMModelToModel method, of class ModelConverter. 
    */ 
    @Test 
    public void testSIMModelToModel() { 
     System.out.println("SIMModelToModel"); 
     SIMModel simModel = new PESMModel(); 
     simModel.addState(testState); 
     Model expResult = null; 
     Model result = ModelConverter.SIMModelToModel(em, simModel); 
     assertTrue(expResult!=null); 
     // TODO review the generated test code and remove the default call to fail. 
     //fail("The test case is a prototype."); 
    } 
} 

,並運行它時,我得到以下錯誤:

java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/PersistenceContextType 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:787) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:447) 
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
    at java.lang.Class.getDeclaredMethods0(Native Method) 
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) 
    at java.lang.Class.getDeclaredMethods(Class.java:1808) 
    at sun.reflect.annotation.AnnotationType$1.run(AnnotationType.java:104) 
    at sun.reflect.annotation.AnnotationType$1.run(AnnotationType.java:101) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:100) 
    at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:84) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:221) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:88) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:70) 
    at java.lang.reflect.Field.declaredAnnotations(Field.java:1033) 
    at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:1026) 
    at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:196) 
    at org.junit.runners.model.FrameworkField.getAnnotations(FrameworkField.java:26) 
    at org.junit.runners.model.TestClass.addToAnnotationLists(TestClass.java:52) 
    at org.junit.runners.model.TestClass.<init>(TestClass.java:45) 
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:73) 
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55) 
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13) 
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) 
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29) 
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) 
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24) 
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:51) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) 
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) 
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) 
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68) 

我的persistence.xml文件是:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="PU" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>jdbc/modelsystemdb</jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <properties/> 
    </persistence-unit> 
</persistence> 

我應該怎麼做才能使測試運行?

+4

如果您使用的是真正的JPA提供程序,而不是模擬接口,那麼這不是一個單元測試,而是一個集成測試。這絕對沒問題 - 但你不應該稱之爲單元測試。 – 2012-07-24 17:55:56

+0

你說得對,我編輯了這個問題。 – 2012-07-24 19:15:49

回答

3

由亞當邊引用Trouble With Crippled Java EE 6 APIs in Maven Repository And The Solution

Instead of using

<dependency> 
    <groupId>javax</groupId> 
    <artifactId>javaee-web-api</artifactId> 
    <version>6.0</version> 
    <scope>provided</scope> 
</dependency> 

You should use alternative (geronimo, jboss etc.) dependencies:

<dependency> 
    <groupId>org.apache.geronimo.specs</groupId> 
    <artifactId>geronimo-ejb_3.1_spec</artifactId> 
    <version>1.0</version> 
    <scope>provided</scope> 
</dependency> 
<dependency> 
    <groupId>org.apache.geronimo.specs</groupId> 
    <artifactId>geronimo-jpa_2.0_spec</artifactId> 
    <version>1.0</version> 
    <scope>provided</scope> 
</dependency> 
+0

謝謝!但我沒有包含在我的pom中的依賴關係。我有javaee-api。試圖將其刪除,但無法找到完整的替代品。另外,我嘗試了你給予我和Jboss的依賴關係,但沒有奏效。儘管我正在和Glassfish一起工作,並沒有找到一個替代軟件包:S – 2012-07-24 16:48:42

+0

'javaee-api'可以編譯,但是* *不能*在運行時使用它。您*必須*從提供商處獲得適當的API實施。我使用'org.hibernate.javax.persistence:hibernate-jpa-2.0-api',它包含JPA 2 API,沒有別的。即使你不使用Hibernate,也可以使用它,因爲它只是API。 – 2012-07-24 17:54:18

+0

我已經添加了依賴關係:S – 2012-07-24 19:13:33

1

如果你想在測試中使用JPA,那麼你將需要你的時候有classpath中的JPA提供商運行它們。您可以編譯爲javaee-api,但是您必須在運行時擁有一個真正的實時提供程序。

您提到您正在使用GlassFish;它使用EclipseLink作爲它的提供者,所以它對你的測試也是有意義的。他們的wiki上有information about using EclipseLink via Maven

+0

謝謝湯姆,但我正在尋找使它與hibernate一起工作,這可能嗎? – 2012-07-24 19:11:44

+0

當然!相反,只需添加相關的Hibernate依賴關係即可。我有'org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final'作爲編譯依賴項,'org.hibernate:hibernate-entitymanager:4.1.4.Final'作爲運行時依賴項。那些加上他們的傳遞依賴是我需要使用Hibernate。那麼,和一個數據庫驅動程序。和某種後端記錄,雖然實際上,我還沒有想出來。 – 2012-07-24 20:51:38

+0

對不起湯姆,非常感謝你的時間,但我已經安裝了這些依賴關係。我找不到部署到Glassfish的情況下運行測試的方法。 – 2012-07-24 21:29:08

0

我們遇到了一個非常類似的問題:Junit測試在Maven構建期間成功執行,但是試圖從Eclipse直接運行它們顯示了這個糟糕的「缺席代碼」錯誤。該解決方案不在pom.xml-s中(它們必須是正確的,因爲您的構建運行,對嗎?),但在eclipse中配置Junit執行。在我們的例子中,當Maven依賴關係在項目本身之上移動時,加載正確的實現(eclipselink 2.0.4)持久化類。因此,在eclipse中嘗試檢查「運行配置...」,選擇有問題的Junit配置和「類路徑」選項卡,更改「用戶條目」部分中庫的順序:將Maven依賴關係移到頂部。

最好的問候, 喬公

2

也有類似的問題。即使Hibernate JPA jar可以通過傳遞依賴並且提供了javaee 6.0依賴,但JUNIT測試用例失敗了。我剛剛在pom文件的依賴關係定義的末尾移動了javaee依賴項,以便在類路徑解析期間,Java EE jar之前出現休眠JPA api jar。這似乎是訣竅,我能夠運行測試用例。希望這可以幫助。休眠依賴

<dependency> 
     <groupId>javax</groupId> 
     <artifactId>javaee-api</artifactId> 
     <version>6.0</version> 
     <scope>provided</scope> 
    </dependency> 
+0

+1:我已經有了這個相同的保時捷在我的POM底部使用javaee-api。很高興把它縮小到Hibernate排序,現在我想起來似乎很明顯。 :-) – 2014-11-05 12:17:13

0

在根據對項目運行配置/類路徑我的情況後

<dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>${hibernate.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>${hibernate.version}</version> 
    </dependency> 

JavaEE的出現,單擊編輯並檢查的伎倆「只包含導出條目」。