如何在 JUnit4 中使用休眠测试 DAO

Posted

技术标签:

【中文标题】如何在 JUnit4 中使用休眠测试 DAO【英文标题】:How to test DAOs using hibernate in JUnit4 【发布时间】:2012-12-29 10:16:47 【问题描述】:

这似乎是一个类似的问题 (Test DAO in java using Junit4 and Hibernate),但他正在成功创建会话。我无法创建会话。

请注意,我没有使用 Spring。我只需要测试使用 HibernateUtil.java 创建会话的 DAO

我的示例测试代码(在测试包中)

public void testGetBean() 
    System.out.println("getBean");
    int idaccount = 0;
    Account expResult = null;
    Account result = DAOAccount.getBean(idaccount);
    assertEquals(expResult, result);
    // TODO review the generated test code and remove the default call to fail.
    //fail("The test case is a prototype.");

这里是 DAOAccount getBean()(在源包中)

public static Account getBean(int idaccount) 
    Account ac = null;
    Session sess = NewHibernateUtil.getSessionFactory().openSession();
    Transaction tx = sess.beginTransaction();
    Query q = sess.createQuery("from Account where idaccount=:id");
    q.setInteger("id", idaccount);
    ac = (Account) q.uniqueResult();
    tx.commit();
    sess.close();
    return ac;

NewHibernateUtil.java(在源包中)

public class NewHibernateUtil 
private static final SessionFactory sessionFactory;

static 
    try 
        // Create the SessionFactory from standard (hibernate.cfg.xml) 
        // config file.
//            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        sessionFactory = new Configuration().configure().buildSessionFactory();
     catch (Throwable ex) 
        // Log the exception. 
        System.err.println("Initial SessionFactory creation failed." + ex);
        throw new ExceptionInInitializerError(ex);
    


public static SessionFactory getSessionFactory() 
    return sessionFactory;


这是堆栈跟踪

以下是项目结构:

@Subin 询问的实际异常堆栈跟踪

[2012-12-29 16:36:24.347] [ INFO] Configuration.applyHibernateValidatorLegacyConstraintsOnDDL:1646 - Hibernate Validator not found: ignoring
Initial SessionFactory creation failed.java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/validation/Validation
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/validation/Validation
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:170)
    at org.hibernate.cfg.beanvalidation.BeanValidationActivator.applyDDL(BeanValidationActivator.java:103)
    at org.hibernate.cfg.Configuration.applyBeanValidationConstraintsOnDDL(Configuration.java:1674)
    at org.hibernate.cfg.Configuration.applyConstraintsToDDL(Configuration.java:1624)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1415)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1826)
    at dao.NewHibernateUtil.<clinit>(NewHibernateUtil.java:25)
    at dao.DAOAccount.getAccounts(DAOAccount.java:77)
    at dao.DAOAccountTest.testGetAccounts_User(DAOAccountTest.java:78)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at junit.framework.TestCase.runTest(TestCase.java:176)
    at junit.framework.TestCase.runBare(TestCase.java:141)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:129)
    at junit.framework.TestSuite.runTest(TestSuite.java:255)
    at junit.framework.TestSuite.run(TestSuite.java:250)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)

【问题讨论】:

发布异常跟踪 @Subin 我已经编辑了问题并添加了异常跟踪。 请看我的回答,hibernate.cfg.xml 在类路径中吗? 使用 ex.printStackTrace() 记录实际异常 【参考方案1】:

公共配置configure() 抛出休眠异常 使用名为 hibernate.cfg.xml 的应用程序资源中指定的映射和属性。 抛出:HibernateException

Configuration.configure() 仅当hibernate.cfg.xml 可用作应用程序资源时才能正常工作。或类路径。

如果您使用 eclipse 来调用您的 Junit 测试,请将 hibernate.cfg.xml 添加到类路径中,因为您使用的是 maven,您是否在 src/main/resources 中有它

请查看此链接以了解为什么会发生 java.lang.ClassFormatError: 发生。 Maven: hibernate-entitymanager together with javaee-api break my unit tests

【讨论】:

我正在使用 Netbeans 6.9 来调用测试,是的,我在 src/main/resources 中有配置 xml。 是否命名为 hibernate.cfg.xml ? 是的,它被命名为 hibernate.cfg.xml。它在正常运行项目时也很完美。只有测试不起作用。我已编辑问题以显示项目结构。 您可以使用打印堆栈跟踪记录实际异常catch (Exception ex) // ex.printStackTrace() System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); ,如图所示。 我已经添加了完整的堆栈跟踪。

以上是关于如何在 JUnit4 中使用休眠测试 DAO的主要内容,如果未能解决你的问题,请参考以下文章

JUnit4注解

如何使用 Maven surefire 排除具有给定类别的所有 JUnit4 测试?

如何使用junit4写单元测试用例

Spring项目使用Junit4测试配置

如何将JUnit 4测试添加到JUnit 3测试套件中

junit4使用心得