2012-05-19 20 views
4

我正在通过Smith和Ledbrook的Grails in Action。本书中的例子是针对Grails 1.1和Hibernate 1.1编写的(根据下载的源代码的application.properties)。Grails 1.1应用程序的集成测试不适用于Grails 2.0.3。它可能是GORM配置问题吗?

其中一个例子是“喧哗”。我的机器上装有Grails 2.0.3。我使用“grails create-app hubbub”创建了我自己的应用程序副本,创建了我的域类并使用Grails命令进行了测试,然后在本书的源代码中键入。换句话说,我并不试图运行在Grails 2.0.3环境中使用Grails 1.1生成的源代码树。 Grails 2.0.3生成了不是该示例唯一的所有配置和类。我只是在第一个地方输入了非Grails生成的例子中的少量源代码。

这是我的问题 - 其中一个集成测试使用save()方法来保存对象。当我运行测试时,它只包含一个save(),它会成功。如果测试包含一个以上的save()方法,不过,所有调用保存()后的第一个失败:

| Failure: testSaveAndUpdate(com.grailsinaction.UserIntegrationTests) 
| groovy.lang.MissingMethodException: No signature of method: 
    com.grailsinaction.User.save() is applicable for argument 
    types:() values: [] 
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), 
    any(), wait(long) 
at 
com.grailsinaction.UserIntegrationTests.testSaveAndUpdate 
(UserIntegrationTests.groovy:46) 

我已经重新安排了调用保存(),和第一一个总是有效,而随后的调用总是失败。我已经注释掉了测试来运行每个调用来自行保存,并且每个人都可以自行成功。

这里是在我称之为save()方法的类:

package com.grailsinaction 

class User { 

String userId 
String password 
String homepage 
Date dateCreated 

static constraints = { 
    userId(size: 3..20, unique: true) 
    password(size: 6..8) 
    homepage(url: true, nullable: true) 
} 

下面是关于用户的集成测试调用保存():

package com.grailsinaction 

import grails.test.* 

class UserIntegrationTests extends GrailsUnitTestCase { 

void testFirstSaveEver() { 
    def user = new User(userId: 'joe', password: 'secret', 
     homepage: 'http://www.grailsinaction.com') 
    assertNotNull user.save() 
    assertNotNull user.id 

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

void testSaveAndUpdate() { 
    def user = new User(userId: 'joe', password: 'secret', 
     homepage: 'http://www.grailsinaction.com') 
    assertNotNull user.save() 

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

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

这是从数据配置我生成的DataSource.groovy(所有环境,但为简洁起见编辑了测试):

dataSource { 
    pooled = true 
    driverClassName = "org.h2.Driver" 
    username = "sa" 
    password = "" 
} 
hibernate { 
    cache.use_second_level_cache = true 
    cache.use_query_cache = false 
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' 
} 
// environment specific settings 
environments { 
    development { 
     ... 
    } 
    test { 
     dataSource { 
      dbCreate = "update" 
      url = "jdbc:h2:mem:testDb;MVCC=TRUE" 
     } 
    } 
    production { 
     dataSource { 
      ... 
      } 
     } 
    } 
} 

下面是从书中原文:

dataSource { 
    pooled = true 
    driverClassName = "org.hsqldb.jdbcDriver" 
    username = "sa" 
    password = "" 
} 
hibernate { 
    cache.use_second_level_cache=true 
    cache.use_query_cache=true 
    cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider' 
} 
// environment specific settings 
environments { 
    development { 
     dataSource { 
      ... 
     } 
    } 
    test { 
     dataSource { 
      dbCreate = "update" 
      url = "jdbc:hsqldb:mem:testDb" 
     } 
    } 
    production { 
     dataSource { 
      ... 
     } 
    } 
} 

最大的区别在于跳出的是,原来司机是org.hsqldb.jdbcDriver,而一个Grails的2.0.3采用的是org.h2.Driver。另一个主要区别是原始数据源url是jdbc:hsqldb:mem:testDb,而新数据源是jdbc:h2:mem:testDb; MVCC = TRUE。最后,指定的缓存机制差异很大。

难道这是一个配置问题,必须做一些与h2和hsqldb之间的差异?如果是这样,那么我有什么最好的地方去了解我需要做些什么才能做到这一点?

回答

6

在grails 2中,你不应该在集成测试中扩展GrailsUnitTestCase,将其更改为GroovyTestCase,你应该摆脱这个问题。

由于GrailsUnitTestCase认为这是一个单元测试,必须从域对象中模拟(然后拆除并移除)GORM方法。它没有意识到它有真正的方法,而不是嘲笑。

+0

谢谢。现在正在工作。现在你已经指出了这一点,在从单元测试类派生的类中运行集成测试似乎很古怪,但是我会浪费大量时间来重新配置Hibernate,并且从未注意到这一点。 –

相关问题