2011-04-18 117 views
4

我正在學習書籍「Grails In Action」中的grails,我試圖從示例中運行集成測試。在本書中,它表示每個集成測試功能都應該在每次測試結束時回滾操作。它不回滾每個事務(因爲當我完成數據庫是骯髒的)。我試圖找出原因並找到了一個名爲「事務性」的屬性。據稱你將這個屬性設置爲true,它會使測試用例成爲事務性的,但它似乎沒有改變行爲。我已經在下面列出了單元測試的代碼。Grails集成測試不會倒退

我正在使用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 ][email protected]: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 ][email protected]:28:46,897:groovy.util.GroovyTestCase: Test Case: testCreateUser() 
--Output from testSaveAndUpdate-- 
[INFO ][email protected]:28:47,534:groovy.util.GroovyTestCase: Test Case: testSaveAndUpdate() 
--Output from testSaveThenDelete-- 
[INFO ][email protected]:28:47,568:groovy.util.GroovyTestCase: Test Case: testSaveThenDelete() 
--Output from testValidation-- 
[INFO ][email protected]:28:47,642:groovy.util.GroovyTestCase: Test Case: testValidation() 
[INFO ][email protected]: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 

回答

9

默認情況下,測試(和服務)是事務性的,因此您通常只在false時指定靜態transactional屬性。如果你沒有指定方言,它可能是自動檢測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' 
} 
+0

非常感謝,這是方言的設置。請注意(對於其他人可能會看到這一點),如果表格是在添加/更改方言設置之前創建的,則必須刪除表格並重新創建它們以使其起作用。我第一次嘗試時,我只是離開了現有的表格,並沒有奏效。再次感謝,這解決了我的問題。 – jmq 2011-04-18 02:44:23

0

我有同樣的問題。

  • 在我的情況下,

環境:STS(IDE)中,MySQL(數據庫)

Grails的集成測試必須回滾你知道(默認)。

'grails集成測試'嘗試在每次測試結束時回滾。

如果你的數據庫不支持事務..?

我改變自動創建數據庫表來直接創建表,選項Type = InnoDB。所以我可以解決它。

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

  • 我是韓國學生。我會說一點英語。請嘗試理解我。