4

私はSmithとLedbrookのGrailsinActionで作業しています。この本の例は、Grails1.1およびHibernate1.1に対して作成されています(ダウンロードされたソースのapplication.propertiesによる)。

その一例が「ハバブ」です。私のマシンにはGrails2.0.3があります。「grailscreate-apphubbub」を使用してアプリケーションの独自のコピーを作成し、Grailsコマンドを使用してドメインクラスとテストを作成してから、本のソースを入力しました。つまり、Grails2.0.3環境でGrails1.1を使用して生成されたソースツリーを実行しようとはしていません。Grails 2.0.3は、例に固有ではないすべての構成とクラスを生成しました。そもそもGrailsによって生成されなかった例の少量のソースを入力しただけです。

これが私の問題です-統合テストの1つは、save()メソッドを使用してオブジェクトを永続化します。テストを実行し、save()が1つだけ含まれている場合、成功します。ただし、テストに複数の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()の呼び出しを再配置しましたが、最初の呼び出しは常に機能しますが、後続の呼び出しは常に失敗します。自分で保存するために各呼び出しを実行するテストをコメントアウトしました。すべての人が自分で成功することができます。

これが私が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)
}

ユーザーに対してsave()を呼び出す統合テストは次のとおりです。

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であるのに対し、Grails2.0.3が使用するドライバーはorg.h2.Driverであるということです。他の主な違いは、元のデータソースのURLがjdbc:hsqldb:mem:testDbであるのに対し、新しいデータソースのURLはjdbc:h2:mem:testDb; MVCC=TRUEであるということです。最後に、指定されたキャッシュメカニズムはかなり異なります。

これは、h2とhsqldbの違いで何かをしなければならない構成の問題でしょうか?もしそうなら、これを機能させるために私が何をする必要があるかを理解するために私が行くのに最適な場所は何ですか?

4

1 に答える 1

6

GrailsUnitTestCaseGrails 2 では、統合テストで拡張することは想定されていません。これを変更してGroovyTestCase、問題を取り除く必要があります。

GrailsUnitTestCaseこれは、ドメイン オブジェクトから GORM メソッドをモックする (そして破棄して削除する) 必要がある単体テストであると考えているため、失敗します。モックではなく、実際のメソッドがあることを認識していません。

于 2012-05-19T04:02:15.580 に答える