【问题标题】:Grails Integration Test Does NOT RollbackGrails 集成测试不回滚
【发布时间】:2011-04-18 01:45:02
【问题描述】:

我正在从“Grails In Action”一书中学习 grails,并且我正在尝试从示例中运行集成测试。在书中它说每个集成测试功能都应该在每个测试完成时回滚其操作。它不会回滚每个事务(因为当我完成数据库时是脏的)。我试图找出原因并发现找到了一个名为“事务性”的属性。据称,您将此属性设置为 true ,它将使测试用例具有事务性,但它似乎不会改变行为。我在下面包含了单元测试的代码。

我正在使用 grails 1.3.7 并连接到 MySql 数据库。测试成功运行,它只是不回滚。我在这个集成测试中做错了什么,它跳过了回滚吗?

UserIntegrationTests.groovy:

package com.grailsinaction

import framework.TestTools

class UserIntegrationTests extends GroovyTestCase {
    static transactional = true

    protected void setUp() {
        super.setUp()
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testCreateUser() {
        TestTools.banner(log, "testCreateUser()")

        def user = new User(userId:"joe", password:"secret")
        assertNotNull user.save()
        assertNotNull user.id

        def foundUser = User.get(user.id)
        assertEquals 'joe', foundUser.userId
    }

    void testSaveAndUpdate() {
        TestTools.banner(log, "testSaveAndUpdate()")

        def user = new User(userId:"joe2", password:"secret")
        assertNotNull user.save()

        def foundUser = User.get(user.id)
        foundUser.password = 'sesame'
        foundUser.save()

        def editedUser = User.get(user.id)
        assertEquals 'sesame', editedUser.password
    }

    void testSaveThenDelete() {
        TestTools.banner(log, "testSaveThenDelete()")

        def user = new User(userId: 'joe3', password: 'secret')
        assertNotNull user.save()

        def foundUser = User.get(user.id)
        foundUser.delete()
        assertFalse User.exists(foundUser.id)
    }

    void testValidation() {
        TestTools.banner(log, "testValidation()")

        def user = new User(userId: 'chuck-norris', password: 'tiny')
        assertFalse user.validate()
        assertTrue user.hasErrors()

        def errors = user.errors
        assertNotNull errors

        errors.allErrors.each {
            log.info("field: ${it.field}, code=${it.code}, rejected=${it.rejectedValue}")
        }
    }
}

User.groovy

package com.grailsinaction

class User {
    String userId
    String password
    Date dateCreated
    Profile profile

    static constraints = {
        userId(size: 3..20, unique: true)
        password(size: 6..8, validator: {password, user ->
            return (password != user.userId)
        })
        dateCreated()
        profile(nullable: true)
    }

    static mapping = {
        profile lazy: false
    }

    static hasMany = [posts : Post]
}

测试执行日志

Testing started at 8:28 PM ...
Welcome to Grails 1.3.7 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: C:\Users\jmquigley\workspace\apps\Grails\grails-1.3.7
Base Directory: C:\Users\jmquigley\workspace\samples\lang-grails\hubbub
Resolving dependencies...
Dependencies resolved in 963ms.
Running script C:\Users\jmquigley\workspace\apps\Grails\grails-1.3.7\scripts\TestApp.groovy
Environment set to test
  [groovyc] Compiling 1 source file to C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\classes
    [mkdir] Created dir: C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\test-reports\html
    [mkdir] Created dir: C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\test-reports\plain
Starting integration test phase ...
  [groovyc] Compiling 1 source file to C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\classes
  [groovyc] Compiling 1 source file to C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\classes
[INFO ]20110417@20:28:42,959:grails.spring.BeanBuilder: [RuntimeConfiguration] Configuring data source for environment: TEST
  [groovyc] Compiling 1 source file to C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\test-classes\integration
-------------------------------------------------------
Running 4 integration tests...
Running test com.grailsinaction.UserIntegrationTests...
--Output from testCreateUser--
[INFO ]20110417@20:28:46,897:groovy.util.GroovyTestCase: Test Case: testCreateUser()
--Output from testSaveAndUpdate--
[INFO ]20110417@20:28:47,534:groovy.util.GroovyTestCase: Test Case: testSaveAndUpdate()
--Output from testSaveThenDelete--
[INFO ]20110417@20:28:47,568:groovy.util.GroovyTestCase: Test Case: testSaveThenDelete()
--Output from testValidation--
[INFO ]20110417@20:28:47,642:groovy.util.GroovyTestCase: Test Case: testValidation()
[INFO ]20110417@20:28:47,668:groovy.util.GroovyTestCase: field: password, code=size.toosmall, rejected=tiny
null
PASSED
Tests Completed in 1173ms ...
-------------------------------------------------------
Tests passed: 4
Tests failed: 0
-------------------------------------------------------
[junitreport] Processing C:\Users\jmquigley\workspace\samples\lang-grails\hubbub\target\test-reports\TESTS-TestSuites.xml to C:\Users\JMQUIG~1\AppData\Local\Temp\null90011239
[junitreport] Loading stylesheet C:\Users\jmquigley\workspace\apps\Grails\grails-1.3.7\lib\junit-frames.xsl
[junitreport] Transform time: 415ms
[junitreport] Deleting: C:\Users\JMQUIG~1\AppData\Local\Temp\null90011239
Tests PASSED - view reports in target\test-reports
Application context shutting down...
Application context shutdown.

Process finished with exit code 0

【问题讨论】:

    标签: grails groovy grails-domain-class


    【解决方案1】:

    默认情况下测试(和服务)是事务性的,因此您通常只在静态transactional 属性为false 时指定它。如果您没有指定方言,它可能会自动检测 MySQL,但是这些表是使用可能是 MyISAM 的默认引擎创建的。非事务性的 MyISAM 表。确保在使用 MySQL 时指定 InnoDB 方言,例如

    test {
       dataSource {
          dialect= org.hibernate.dialect.MySQLInnoDBDialect
          driverClassName = 'com.mysql.jdbc.Driver'
          username = '...'
          password = '...'
          url = '...'
          dbCreate = 'update'
       }
    }
    

    或者,如果您在所有环境中都使用 MySQL,则可以将其移至顶层,例如

    dataSource {
       pooled = true
       dialect = org.hibernate.dialect.MySQLInnoDBDialect
       driverClassName = 'com.mysql.jdbc.Driver'
    }
    

    【讨论】:

    • 非常感谢,是方言设置。请注意(对于可能看到此内容的其他任何人),如果在添加/更改方言设置之前创建了表,则必须删除表并重新创建它们才能工作。我第一次尝试它时,我只是离开了现有的桌子,但它没有用。再次感谢,这解决了我的问题。
    【解决方案2】:

    我有同样的问题。

    • 就我而言,

    环境:STS(IDE)、mysql(数据库)

    grails 集成测试必须回滚(默认)。

    “grails 集成测试”尝试在每个测试完成后回滚。

    如果您的数据库不支持事务..?

    我将自动创建数据库表更改为直接创建表,选项 Type=InnoDB。所以我可以解决它。

    create table something( ... ) Type=InnoDB;

    • 我是韩国学生。我会说一点英语。请试着理解我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-28
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多