【问题标题】:Using JUnit to test my dao layer : Spring and hibernate with JavaConfig使用 JUnit 测试我的 dao 层:Spring and hibernate with JavaConfig
【发布时间】:2014-09-01 19:06:45
【问题描述】:

我正在开发一个使用 hibernate 和 spring security 的 spring web 应用程序。

在实现 DAO(使用通用 dao 模式)并为 spring 安全性创建 CustomUserDetailService 和 CustomUserDetails 后,似乎我无法登录(我在内存中使用 id 并且它正在工作)所以我认为它必须是我的 DAO 有问题。

1) 我将 JavaConfig 用于我的配置和这个初始化程序:

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { AppConfig.class,SecurityConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}

我以前从未使用过 JUnit 测试,而且我发现的所有示例都使用 xml 配置,所以我需要一些帮助,一个示例会很棒。

2) 由于我无法使用 JUnit,我试图了解问题所在,因此我添加了一个控制器方法,在该方法中我可以获取一些用户并在页面中显示它们,但我的 GlobalException 处理程序拦截了它并将我重定向到出现此异常的错误页面:

org.springframework.orm.hibernate4.HibernateSystemException: No Session found for current thread; nested exception is org.hibernate.HibernateException: No Session found for current thread

这是我的 GenericDaoImpl:

public class GenericDaoImpl<T,ID extends Serializable> implements GenericDao<T,ID> {


    private Class<T> persistentClass;

    @SuppressWarnings("unchecked")
    public GenericDaoImpl(Class<T> persistentClass) {
        this.persistentClass = persistentClass;
    }

    @Autowired
    private SessionFactory sessionFactory;

    public Session getSession()
    {
        return sessionFactory.getCurrentSession();
    }


    @Override
    public boolean create(T t) {

        if (t== null)  return false;
        getSession().saveOrUpdate(t);
        return true;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T getById(ID id) {

         return (T) getSession().get(persistentClass,id);
    }

    @Override
    public boolean update(T t) {

        if (t==null) return false;
        getSession().update(t);
        return true;
    }

    @Override
    public boolean delete(T t) {

        if (t==null) return false;
        getSession().delete(t);
        return true;
    }

    @Override
    public boolean deleteById(ID id) {
        T t =getById(id);
        if (t==null) return false;
        getSession().delete(t);
        return true;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findByOneCriteria(Criterion criterion) {
        Criteria criteria = getSession().createCriteria(persistentClass);
        criteria.add(criterion);
        return (List<T>)criteria.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findByCriterias(ArrayList<Criterion> criterions) {
        Criteria criteria = getSession().createCriteria(persistentClass);
        for (Criterion c : criterions)
        criteria.add(c);
        return (List<T>)criteria.list();
    }
}

还有我的 PersonnelDaoImpl:

@Repository
public class PersonnelDaoImpl extends GenericDaoImpl<Personnel,Integer> implements PersonnelDao {

    public PersonnelDaoImpl(){
        super(Personnel.class);
    }

    @Override
    public Personnel findByUsername(String username) {
       List<Personnel> result = findByOneCriteria(Restrictions.like("username",username));
       return result.get(0);
    }

    @Override
    public List<Personnel> findByRole(int role) {
        return findByOneCriteria(Restrictions.eq("role",role));
    }
}

我不明白怎么了。

【问题讨论】:

  • 您尝试登录时是否遇到异常?
  • 我解决了问题的第二部分(我添加了一个答案),并回答了你的问题:不,我得到的例外是当我测试我的服务时(我做了一个可以访问的页面即使用户没有登录,并且使用了用于登录的服务)并且我得到了上述异常

标签: spring hibernate junit


【解决方案1】:

使用 Java 为测试用例创建配置,

在您的测试类中使用这些注释。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Config.class})
public class ServiceTest{

}

Config.class 看起来像,

@Configuration
public class Config {
}

在 Config 类中定义 bean 并执行测试用例。

2) 很明显,No session 表示在调用 DAL 的层中没有定义TransactionManager

尝试使用@Transactional,它会为您做到这一点。

注意:请确保@Transactional 允许默认为transactionManager 的值属性

【讨论】:

  • 2) 我想到了,我添加了一个答案,现在的问题是单元测试,它似乎不像你上面描述的那样工作(我已经尝试过了),没有它也需要初始化程序吗?如果是,如何包含它?
  • 为什么当每件事都应该被嘲笑时,单元测试需要事务管理器?你的意思是集成测试?
  • 我正在使用单元测试来检查我的服务是否正常工作,或者至少,我想检查我的存储库是否正常工作,如果有其他解决方案,请成为我的客人^_^
【解决方案2】:

关于第二部分 2),我找到了解决方案,我必须将 @Transactional 添加到我的服务中,this 帖子帮助了我

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-24
    • 2014-06-21
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多