我有一个名为HibernateUtil的辅助类,它创建一个SessionFactory并返回一个会话。该类工作正常,但它会产生模拟问题,因为Mockito不能使用静态方法。
简单的解决方案似乎创建了一个类的实例,除了我需要确保应用程序中只有一个SessionFactory。如果不使用静态方法,我该怎么做?
public class HibernateUtil {
private static final Log logger = LogFactory.getLog(SessionFactory.class);
private static final SessionFactory sessionFactory = createSessionFactory();
private static SessionFactory createSessionFactory() {
logger.info("createSessionFactory called");
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
return configuration.buildSessionFactory(builder.build());
}
private static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() {
Session session = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
if (!session.isOpen()) {
session = HibernateUtil.getSessionFactory().openSession();
}
} catch (Exception e) {
e.printStackTrace();
}
return session;
}
}
编辑:感谢您的回复!我想我会把它叫做一个晚上,并明天早上再次解决这个问题。
答案 0 :(得分:0)
另一种方法是使用依赖注入,但是通过代码的外观,你不会这样做。 您可以使用Spring或其他IoC容器来执行IoC ...或diy-di
另一个替代方案(虽然有点hacky)是拥有相同的“静态”接口,但委托给另一个可以在测试中替换的对象。默认情况下,后备实现使用Hibernate,在测试中,您可以使用模拟实例替换该实现。
答案 1 :(得分:0)
如果您不想使用spring hibernate支持,可以将课程更改为:
package com.captain.oh.captain
@Component // singletonbean
public class HibernateUtil {
private static final Log logger = LogFactory.getLog(SessionFactory.class);
private SessionFactory sessionFactory;
@PostConstruct
private void createSessionFactory() {
logger.info("createSessionFactory called");
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
}
private SessionFactory getSessionFactory() {
return sessionFactory;
}
public Session getSession() {
Session session = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
if (!session.isOpen()) {
session = HibernateUtil.getSessionFactory().openSession();
}
} catch (Exception e) {
e.printStackTrace();
}
return session;
}
}
并autowire
在另一个组件(@Autowired HibernateUtil
)中。不要忘记将软件包(com.captain.oh.captain
)添加到您的扫描包中(application-context.xml
或@Configuration
类)
另请注意,您的getSession
方法不是Thread-safe
答案 2 :(得分:0)
不要直接在代码中使用HibernateUtil,而是将其隐藏在界面后面:
public interface HibernateSessionProvider() {
Session getSession();
}
使用默认实现:
public class DefaultHibernateSessionProvider() implements HibernateSessionProvider {
@Override
public Session getSession() {
return HibernateUtil.getSession();
}
}
然后你可以在测试期间模拟HibernateSessionProvider。这种方法可以使用或不使用Sprting的依赖注入。