2012-02-15 9 views
0

Grails 2.0.0を使用する私は作成されたサービスで、Playerクラスのインスタンスを作成してデータベースに保存します。次に、JUnitの統合テストで、Player.saveで制約の検証が失敗した場合(failOnError:true)、サービスメソッドcreateNewPlayer(String platformID)が例外をスローすることを確認します。制約の検証が失敗した後にメモリ内に無効なオブジェクトがあります

すべてはうまく行くが、私は呼び出しだ場合の方法shouldFail(...)の後:

--Output from testCreatingNewPlayerWithExistingID-- 
| Error 2012-02-15 21:52:05,293 [main] ERROR hibernate.AssertionFailure - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) 
Message: null id in test1.Player entry (don't flush the Session after an exception occurs) 

私の質問は::テストする方法

assert Player.list().size() == 1; 

私はこのエラーを取得していますshouldFailメソッド内で例外をスローし、Hibernateがこの後にnull IDを持つPlayerクラスの無効なインスタンスをメモリに保持しないようにしますか?

私のコード例以下は

class WorkingService 
{ 
    Player createNewPlayer(String platformID) throws ValidationException { 
     Player player = new Player(platformID: platformID); 
     return player.save(failOnError : true); 
    } 
} 


class Player 
{ 
    String platformID 
    static constraints = { 
     platformID nullable: false, blank: false, unique: true 
    } 
} 


@TestFor(WorkingService) 
class WorkingServiceTests 
{ 
    WorkingService workingService; 

    void testCreatingNewPlayerWithExistingID() 
    { 
     def player = new Player(platformID: "1"); 
     player.save(flush: true); 

     assert Player.list().size() == 1; 

     shouldFail ValidationException, { 
      player = workingService.createNewPlayer("1"); 
     } 

     assert Player.list().size() == 1; 
    } 
} 

答えて

1

私はこの問題は、あなたが統合テストと単体テストを混合していることだと思います。統合テストではGroovyTestCaseを拡張し、TestForのようなAST変換アノテーションは使用しないでください。これは私のテストアプリケーションに渡します。

import grails.validation.ValidationException 

class WorkingServiceTests extends GroovyTestCase { 

    WorkingService workingService 

    void testCreatingNewPlayerWithExistingID() { 

     new Player(platformID: "1").save(flush: true) 

     assert Player.count() == 1 

     shouldFail(ValidationException) { 
     workingService.createNewPlayer("1") 
     } 

     assert Player.count() == 1 
    } 
} 

関連しない - それはちょうど数を取得するために、すべてのインスタンスをロードするので、あなたは、データベースからカウントを取得するためにlist().size()を使用しないでください。代わりにcount()を使用してください。また、nullable: falseがデフォルトですので、それを指定するのは冗長です。

+0

ありがとう、バート!それは作品です!私がGrailsのユニットテストのドキュメントを完全に理解していないように見え、それを再度読み込まなければなりません。他のヒントをありがとう。 – Sat

関連する問題