2012-07-24 85 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的出现,单击编辑并检查的伎俩“只包含导出条目”。