Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Hibernate添加数据库后的单元测试_Java_Hibernate_Jpa_Junit_Transactions - Fatal编程技术网

Java 使用Hibernate添加数据库后的单元测试

Java 使用Hibernate添加数据库后的单元测试,java,hibernate,jpa,junit,transactions,Java,Hibernate,Jpa,Junit,Transactions,我已经使用hibernate将数据库功能添加到一个系统中,该系统在内存中到目前为止。当所有的数据都存储在内存中时,我可以使用JUnit在每次测试后恢复原始数据 有没有办法通过添加新的hibernate来达到同样的效果? 我所说的“相同的结果”是指从数据库的原始状态开始,进行可以改变数据库的测试,并将数据库恢复到其原始状态 到目前为止,我的想法是: 内存数据库(这是一个Hibernate特性),但这不允许我使用实际数据 向我添加“测试标志”,如果设置,DOA不会提交更改 我确信有更好的解决方案,但

我已经使用hibernate将数据库功能添加到一个系统中,该系统在内存中到目前为止。当所有的数据都存储在内存中时,我可以使用JUnit在每次测试后恢复原始数据

有没有办法通过添加新的hibernate来达到同样的效果? 我所说的“相同的结果”是指从数据库的原始状态开始,进行可以改变数据库的测试,并将数据库恢复到其原始状态

到目前为止,我的想法是:

  • 内存数据库(这是一个Hibernate特性),但这不允许我使用实际数据
  • 向我添加“测试标志”,如果设置,DOA不会提交更改

  • 我确信有更好的解决方案,但我还没有找到更好的解决方案。

    我认为我们应该清楚单元测试的定义。单元测试必须只测试应用程序中的一个小单元(公共方法)

    假设您有一个使用Hibernate与数据库交互的DAO层。现在Hibernate使用需要数据源的SessionFactory。单元测试的数据源不应与生产应用程序的数据源相同

    其思想是定义一个测试数据源并使用内存数据库(hsqldb或任何其他数据库)。对于每个测试用例,您可以使用测试数据源在内存数据库上执行一些查询,并在执行单元测试后清除这些查询。对于每个单元测试,您应该执行查询,以便针对特定测试完成测试数据设置

    例如:如果要测试以下各项: 1) 创建帐户 2) 更新帐户 3) 删除帐户

    然后有三个测试场景,每个场景都可以进行多个单元测试

    现在,在执行createaccount测试之前,DB没有这个帐户是很重要的。然后在DAO中调用createAccount方法来测试相同的结果。无需验证结果是否以DB为单位。只需检查方法的返回,如果它与成功创建帐户时的预期相同,则测试用例应该通过

    对于更新帐户,您的安装方法应该通过查询插入一个帐户,然后您必须在DAO中为此帐户id调用updateAccount,以此类推

    请坚持单元测试的定义,不要一次测试多个功能


    希望这有帮助。

    您可以在每次测试之前启动数据库事务:

    @PersistenceContext
    private EntityManager em; 
    
    @Before
    public void init() {
        em.getTransaction().begin();
    }
    
    @After
    public void destroy() {
        em.getTransaction().rollback();
    }
    

    这样,每个测试都会在测试开始前运行一个事务,并且该事务会在测试完成后回滚,因此您始终会放弃当前测试所做的所有更改。

    首先感谢您的回答,我不确定我的问题的哪一部分给人的印象是我正在使用单元测试来实现更多的一个功能,但我向您保证情况并非如此。我的意思是,我已经编写了许多单元测试,我正试图找到一种方法来修改它们,这样它们就不会损害数据。对于集成测试,我也需要这个,对于一些测试,我更喜欢使用现有数据,而不是使用空白内存数据库,然后自己填充,这就是为什么我要求使用原始数据库并恢复它的方法。目前,假设我想要添加用户——adduser方法创建一个用户实例并调用UserDAO来获取会话、开始事务、添加新用户、提交更改并关闭会话。因此,我认为我无法应用您的解决方案,因为提交是在方法期间完成的;我不能使用这个解决方案。如果您使用的是Spring或JavaEE,因此您只使用@Transactional标记您的服务方法,这将是一个有效的替代方法。您认为在hibernate之上使用Spring或JavaEE更好吗?不管怎样,我都会研究它,但作为一种动机,使用这些工具还能获得什么呢?这更好,因为它们为您带来了一个统一的企业编程模型,这是大多数开发人员已经熟悉的。您可以获得事务管理、AOP/拦截器支持、通用DAO(Spring数据/DeltaSpike)、依赖项注入。