Java 如何测试事务数据库代码?

Java 如何测试事务数据库代码?,java,grails,groovy,transactions,spock,Java,Grails,Groovy,Transactions,Spock,假设您有一些简单的代码,其中在一个事务中将两行插入到数据库中 如何使第二个测试失败,以检查第一个测试是否回滚 如果它是一个Web服务,我会通过元编程来模拟它,以便让第二次调用失败 但对于数据库代码,我不确定。是否有某种jdbc驱动程序会为(比如)每7次操作抛出异常 好的,让我们更具体一点: 假设您有一些遗留代码。它的结构不是很好,但您也不想重构它(让我们先编写一些测试!)。事务行为似乎有问题,您希望测试代码 由于代码基本上可以工作,因此很难通过违反约束使部分代码失败 因此,我想在测试中模拟数据库

假设您有一些简单的代码,其中在一个事务中将两行插入到数据库中

如何使第二个测试失败,以检查第一个测试是否回滚

如果它是一个Web服务,我会通过元编程来模拟它,以便让第二次调用失败

但对于数据库代码,我不确定。是否有某种jdbc驱动程序会为(比如)每7次操作抛出异常

好的,让我们更具体一点:

假设您有一些遗留代码。它的结构不是很好,但您也不想重构它(让我们先编写一些测试!)。事务行为似乎有问题,您希望测试代码

由于代码基本上可以工作,因此很难通过违反约束使部分代码失败


因此,我想在测试中模拟数据库失败(可能是因为死锁、不可用、磁盘已满或类似情况)或“拔掉插头”时发生的情况。集成测试将是测试事务和回滚的适当位置。类似于此示例的内容应该足够了:

package com.example

import grails.test.mixin.integration.Integration
import grails.transaction.*
import spock.lang.*
import org.springframework.beans.factory.annotation.Autowired

@Integration
@Rollback
class TransactionIntSpec extends Specification {

    @Autowired
    FooService service

    void "test transaction rollback"() {
        given: 'bar service throws exception'
        service = Mock(FooService) {
            serviceBar() >> { throw new Exception() }
        }

        when:
        service.serviceMethod()

        then:
        !Foo.count() && !Bar.count()
    }

    void "test transaction successfull"() {
        when:
        service.serviceMethod()

        then:
        Foo.count() && Bar.count()
    }
}
其中
Foo
Bar
只是简单的域类,服务类如下所示:

package com.example

import grails.transaction.Transactional

@Transactional
class FooService {

    def serviceMethod() {
        serviceFoo()
        serviceBar()
    }

    def serviceFoo() {
        new Foo().save(flush: true, failOnError: true)
    }

    def serviceBar() {
        new Bar().save(flush: true, failOnError: true)
    }
}

在Grails 3.0.2中测试过

我很确定你可以用它来做,是的,但是如何。。。找不到示例…对要添加的第二行违反某些约束。任何会导致第二次插入失败的东西都应该足够了,不是吗?我不想测试转换功能,我想测试我的代码在数据库失败或拔出插头时的行为。好的,这里使用的技巧是将方法/事务拆分为可以模拟的子方法。因此,如果
serviceFoo
serviceBar
将是内联的,那么这将不起作用,不是吗?您可以按照@railsgod在评论中的建议进行操作。