DBUnit - 休眠 - org.hibernate.HibernateException: 无法实例化方言 class
DBUnit - Hibernate - org.hibernate.HibernateException: could not instantiate dialect class
我尝试使用 JUNit、DBUnit 和 Hibernate 对我的 class 进行集成测试。
用于数据库的初始化
为了模拟一个孤立的数据库,我使用了这个 tutorial。
请注意,我必须根据允许我设置 hibernate.test.cfg.xml
所在位置的教程创建两个 HibernateUtil class(一个(名为 HibernateUtils.class
),另一个(名为 HibernateSessionFactory
,它基于 hibernate.cfg.xml
)
创建了 SessionFactory
集成测试
我必须测试 Player.class
中的 show_Potions()
方法。
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.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.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...
}
玩家测试
@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;
}
}
错误消息非常明确地说明了问题所在。
检查您的配置并确认您已正确配置方言并且它指向正确的方言 class 名称。如果是,请确保方言确实在 class 路径上(如果它是自定义方言实现)。
我终于找到了这个问题的解决方案。
问题是我在测试中创建了两个 SessionFactory。
即:当我在测试中调用 show_potions()
时,我调用 HibernateSessionFactory.configureSessionFactory()
。但是,该测试扩展了 HibernateDBUnitTestCase,其 setUp()
方法调用 HibernateUtils.newSessionFactory()
。因此,测试不知道它应该使用什么休眠配置。
使用这种方法,您将不需要 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
在设置中,我添加了以下行:
if (sessionFactory == null) {
sessionFactory = HibernateUtils.newSessionFactory("hibernate.test.cfg.xml");
HibernateSessionFactory.setSessionFactory(sessionFactory);
}
就是这样,每当 'real' 程序调用 show_potions()
,HibernateSessionFactory.configureSessionFactory(
) 使用 "hibernate.cfg.xml"
,当测试程序调用 show_potions,它使用 "hibernate.test.cfg.xml"
.
希望对其他人有所帮助。
我尝试使用 JUNit、DBUnit 和 Hibernate 对我的 class 进行集成测试。
用于数据库的初始化
为了模拟一个孤立的数据库,我使用了这个 tutorial。
请注意,我必须根据允许我设置 hibernate.test.cfg.xml
所在位置的教程创建两个 HibernateUtil class(一个(名为 HibernateUtils.class
),另一个(名为 HibernateSessionFactory
,它基于 hibernate.cfg.xml
)
集成测试
我必须测试 Player.class
中的 show_Potions()
方法。
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.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.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...
}
玩家测试
@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;
}
}
错误消息非常明确地说明了问题所在。
检查您的配置并确认您已正确配置方言并且它指向正确的方言 class 名称。如果是,请确保方言确实在 class 路径上(如果它是自定义方言实现)。
我终于找到了这个问题的解决方案。
问题是我在测试中创建了两个 SessionFactory。
即:当我在测试中调用 show_potions()
时,我调用 HibernateSessionFactory.configureSessionFactory()
。但是,该测试扩展了 HibernateDBUnitTestCase,其 setUp()
方法调用 HibernateUtils.newSessionFactory()
。因此,测试不知道它应该使用什么休眠配置。
使用这种方法,您将不需要 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
在设置中,我添加了以下行:
if (sessionFactory == null) {
sessionFactory = HibernateUtils.newSessionFactory("hibernate.test.cfg.xml");
HibernateSessionFactory.setSessionFactory(sessionFactory);
}
就是这样,每当 'real' 程序调用 show_potions()
,HibernateSessionFactory.configureSessionFactory(
) 使用 "hibernate.cfg.xml"
,当测试程序调用 show_potions,它使用 "hibernate.test.cfg.xml"
.
希望对其他人有所帮助。