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

时间:2015-07-04 07:25:13

标签: java grails groovy transactions spock

想象一下,您有一些简单的代码,您可以在一个事务中将两行插入数据库。

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

它是否是一个web服务,我会通过元编程来嘲笑它,以便让第二次调用失败。

但是对于数据库代码我不确定。是否有某种jdbc驱动程序会在每次第7次操作时抛出异常(让我们说)?

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

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

由于代码基本上可行,因此很难使部分内容因违反约束而失败。

所以我想在我的测试中做的是模拟如果数据库失败会发生什么(可能是因为存在死锁,不可用,磁盘已满或者类似的东西),或者当你"拔出插件时## 34。

1 个答案:

答案 0 :(得分:1)

集成测试将是测试事务和回滚的合适位置。像这样的样本就足够了:

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()
    }
}

其中FooBar只是简单的域类,服务类看起来像:

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中测试

相关问题