Grail集成测试用例是否会将数据提交到数据库中

时间:2015-03-13 03:00:08

标签: mysql grails integration-testing

我是Grails的新手,目前正在学习Grails。 我将Mysql配置为我的数据库。当我运行app时,我可以在我的数据库中看到表创建。

我尝试在测试用例中执行save()单元(扩展规范)和集成测试(扩展IntegrationSpec),测试方法如下所示,可以成功传递。

    void "test first save"() {
        when: "when have user id is 'joe', and password is 'secret'"
        def userId = "joe"
        def password = "secret"
        then: "create a user use ${userId} and ${password}"
        User user = new User(userId: userId, password: password, homepage: 'http://www.grailsinaction.com')

        expect: "user can be saved successfully"
        assert user.save(flush:true, failOnError:true)
        assert user.id
        def foundUser = User.get(user.id)
        assert  foundUser?.userId == 'joe'
    }

但我发现在单元和集成测试中没有数据插入数据库。

我理解Unit测试只会模拟持久性,但集成测试应该使用真实数据库进行测试。

所以我的问题是集成是否应该将数据提交到数据库中?如果是这样,任何事情都可能是错误的,没有发生承诺?

1 个答案:

答案 0 :(得分:3)

集成测试运行器配置为为每个测试启动一个新事务,并在测试结束时显式回滚。这很方便,因为您不必在测试之间进行任何清理工作 - 所有内容都会自动重置。请注意,在测试开始之前完成的任何工作(例如在BootStrap中)将保留用于每个测试,因为它已经提交,并且回滚将重置为每次测试开始时的状态。

您可以通过添加

为单个测试类禁用此功能
static transactional = false

但我会避免这种情况,除非在极少数情况下,您正在测试事务提交和回滚,并且需要在该级别进行完全控制。

另请注意,Hibernate dbCreate设置会影响事物。如果将数据配置为在测试运行后保留但使用create-drop,则表将在启动时和关闭时删除,因此使用create(仅在启动时丢弃)或显式迁移将需要查看任何内容。

仅供参考 - 在您的测试中,

def foundUser = User.get(user.id)

不会打到数据库 - Hibernate会简单地返回你刚刚保存的实例。您可以通过启用SQL日志记录来查看此信息。如果要真正重新加载对象,则需要清除Hibernate会话以强制它发出查询。一种简单的方法是使用域类上的withSession方法(它独立于要调用的类,因此使用任何类),例如

User.withSession { session ->
   session.flush()
   session.clear()
}

我添加了flush调用,以确保在清除之前推送的所有内容。