DBUnit - Hibernate - org.hibernate.HibernateException:无法实例化dialect类

时间:2016-06-12 16:52:21

标签: hibernate junit mockito powermock dbunit

我尝试使用JUNit,DBUnit和Hibernate对我的类进行集成测试。

用于数据库的初始化

为了模拟一个孤立的数据库,我使用了这个tutorial

请注意,我必须根据教程创建两个HibernateUtil类(一个(名为HibernateUtils.class),这允许我设置hibernate.test.cfg.xml所在的位置,另一个(名为HibernateSessionFactory它基于hibernate.cfg.xml

创建了SessionFactory

集成测试

我必须从show_Potions()测试Player.class方法。

show_Potions()根据来自数据库的查询设置玩家的魔药。我希望测试在隔离数据库而不是真实数据库中进行查询,因此我采用这种方式:当使用HibernateSessionFactory.configureSessionFactory()时,我们使用' HibernateUtils.newSessionFactory(" hibernate.test.cfg) .XML"。)`

我得到了例外:

 org.hibernate.HibernateException: Could not instantiate dialect class
at org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.constructDialect(DialectFactoryImpl.java:82)
at org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:64)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:146)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:71)
at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2277)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2273)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1742)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1782)
at test.HibernateUtils.newSessionFactory(HibernateUtils.java:27)
at test.HibernateDbUnitTestCase.setUp(HibernateDbUnitTestCase.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassCastException: org.hibernate.dialect.HSQLDialect cannot be cast to org.hibernate.dialect.Dialect
at org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.constructDialect(DialectFactoryImpl.java:73)
... 37 more

java.lang.NullPointerException
at test.HibernateDbUnitTestCase.tearDown(HibernateDbUnitTestCase.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.MethodRoadie.runAfters(MethodRoadie.java:149)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:101)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

您可以看到以下代码。

感谢您的回复。如果您有其他方式可以访问隔离数据库,我很高兴听到它。

Player.class

public class Player extends TablePlayer {

    private List<Item> items;

    //other attributes…

    /*
     * This method set the list of potions of the player based on the query from the database.
     */

    public void show_Potions() throws Exception {

        SessionFactory sf = HibernateSessionFactory.configureSessionFactory();
        Session session = sf.getCurrentSession();
        session.getTransaction().begin();

        try {

            StringBuilder query = new StringBuilder();
            query.append("from TableItems items " +
                    "left join fetch items.name " +
                    "left join fetch items.type " +
                    "left join fetch items.idPlayer player " +
                    "where player.id = :pid ");
            query.append("order by items.dateObtained desc");

        List<TableItems> tableItems = session.createQuery(query.toString()).setParameter(“pid”, this.getId()).list();

        List<Item> potions = new ArrayList<Items>();

        for(TableItems tItem : tableItems){
            Item item = new Item(tItem);
            if(item.getType()).equals(“POTION”){
                potions.add(item);
            }       
        }

        this.setItems( potions );

        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e);
        } finally {
            session.clear();
            session.close();
        }       
    }

    /*
     *  Constructor
     */


    public Player(String id) { // Create a player based on the ID found in the Database
    }

    // other methods...

}

PlayerTest

@RunWith(PowerMockRunner.class)
@PrepareForTest(HibernateSessionFactory.class)
public class PlayerTest extends HibernateDbUnitTestCase {

    private Player player
    private Player player_to_spy;
    private List<Item> actual_items;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        player_to_spy = new Player(“1”);
        player = spy(player_to_spy);
        actual_items = new ArrayList<Item>();
    }

    protected IDataSet getDataSet() throws Exception {  
           return new FlatXmlDataSet(this.getClass().getResourceAsStream("/test/database.xml"));
        }  


    @Test
    public void testShow_Potions() throws Exception {

        PowerMockito.mockStatic(HibernateSessionFactory.class);
        Mockito.when(HibernateSessionFactory.configureSessionFactory()).thenReturn(sessionFactory);     // sessionFactory is an attribute of HibernateDbUnitTestCase
        Mockito.when(HibernateSessionFactory.configureSessionFactory().getCurrentSession()).thenReturn(session); //session is an attribute of HibernateDbUnitTestCase

        player.setId(“1”);      
        player.show_Potions();
        actual_items = player.getItems(); // return the list of items.

        List<Items> expected_items = new ArrayList<Items>();

        Item item1 = new item(“1”); // create an Item of id n°1 based on the database
        expected_items.add(item1);

        assertThat(actual_items,isEqualTo(expected_items)); // I’ve written the isEqualTo() method.
    }

    @After
    public void destroy() throws Exception {
        player_to_spy = null;
        player = null
        actual_items = null;
    }
}

2 个答案:

答案 0 :(得分:1)

错误信息非常明确地表明了问题所在。

检查您的配置并验证您是否已正确配置方言,并且它指向正确的方言类名称。如果是,请确保方言实际上在类路径上,如果它是自定义方言实现。

答案 1 :(得分:0)

我最终找到了解决这个问题的方法。

问题是我在测试中创建了两个SessionFactory。 即:当我在测试中致电show_potions()时,我会拨打HibernateSessionFactory.configureSessionFactory()。但是,测试扩展了HibernateDBUnitTestCase,其setUp()方法调用HibernateUtils.newSessionFactory()。因此,测试不知道它应该使用什么样的hibernate配置。

使用这种方法,你不会需要PowerMock,你必须使用JUnit3,因为DBunit是基于它的。因此,您必须使用Junit3中所需的内容更改@ Test,@ Before和@After。

这就是我解决问题的方法。

1)修改HibernateSessionFactory:

初始版本是:

public class HibernateSessionFactory {

private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;


static {
    try {
        // Create sessionFactory based on hibernate.cfg.xml
        Configuration configuration = new Configuration();
        configuration.configure();
        serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);

    } catch (Throwable ex) {
        System.err.println("Initial SessionFactory creation failed. " + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static SessionFactory configureSessionFactory() throws HibernateException {
    return sessionFactory;
}

}

删除了静态块,并使用以下内容更改了configureSessionFactory()

public static SessionFactory configureSessionFactory() throws HibernateException {
    if(sessionFactory == null) {
        try{
            Configuration configuration = new Configuration();
            configuration.configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed. " + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    return sessionFactory;
}

我也添加了这种方法。

public static void setSessionFactory(SessionFactory factory) 
{ 
    HibernateSessionFactory.sessionFactory = factory; 
} 

2)修改HibernateDbUnitTestCase

在setUp中,我添加了以下行:

if (sessionFactory == null) {  
        sessionFactory = HibernateUtils.newSessionFactory("hibernate.test.cfg.xml");  
        HibernateSessionFactory.setSessionFactory(sessionFactory);

    } 

这就是全部,只要真正的&#39;程序调用{​​{1}},show_potions())使用HibernateSessionFactory.configureSessionFactory(,当测试程序调用show_potions时,它使用"hibernate.cfg.xml"

我希望它能帮助其他人。