0

Grailsの動的getメソッドを使用してドメインオブジェクトを取得しようとすると、Grailsアプリケーションの統合テストでnullオブジェクトが返されます。これは私の問題の単純化された例です。サービスTrackerLogServiceを使用して更新されたログドメインを別のTrackerドメイン用に保存するコントローラーTrackerLogControllerがあるとします。ドメイントラッカー:

class Tracker {

   int id
   String name

   static hasMany = [logs: Log] 
}

ドメインログ:

class Log {
   int id
   String comment

   static belongsTo = [tracker: Tracker]
}

Controller TrackerLogController保存:

def TrackerLogService

def saveTrackerLog() {

   def trackerId = params.trackerId

   def trackerInstance = Tracker.get(trackerId)
   Log log = TrackerLogService.saveTrackerLogs(trackerInstance, params.comment)
   if( log.hasErrors() ){
      //render error page
   }
   //render good page
}

Service TrackerLogService保存:

Log saveTrackerLogs( Tracker tracker, String comment) {
   Log log = new Log(tracker: tracker, comment: comment)
   log.save()
   return log
}

だから今、私はこのサービスの統合テストを書きたいのですが、コントローラーの単純なロジックのためだけにそれを書くべきかどうかわかりません(エラーの場合、エラーページ、それ以外の場合は良いページ)そのための単体テストと、データベース内の永続性をチェックするための統合テスト。

これは私の統合テストのために私が持っているものです:

class TrackerLogServiceTests {

   def trackerLogService

   @Before
   void setUp(){

      def tracker = new Tracker(id: 123, name: "First")

      tracker.save()

      //Now even if I call Tracker.get(123) it will return a null value...
   }

   @Test
   void testTrackerLogService() {
      Tacker trackerInstance  = Tracker.get(123) //I have tried findById as well 

      String commit = "This is a commit" 

      //call the service
      Log log = trackerLogService.saveTrackerLogs(trackerInstance , commit)

      //want to make sure I added the log to the tracker Instance
      assertEquals log , trackerInstance.logs.findByCommit(commit)
   }
}

したがって、この例では、私のtrackerInstanceはnullオブジェクトになります。Grailsの魔法は、モックなしのユニットテストでは機能しないようです。Intigration-そのGrailsの魔法を使用できるDBでの永続性のテストについて考えました。

4

1 に答える 1

3

「割り当て済み」であると宣言しない限り、id値を指定することはできません。現在は自動インクリメントを使用しているため、123の値は使用されません。セキュリティ上の理由から、実際にはマップコンストラクターによって無視されるため、次のようにする必要があります。

def tracker = new Tracker(name: "First")
tracker.id = 123

ただし、自動インクリメントルックアップによって上書きされます。代わりにこのアプローチを使用してください。

class TrackerLogServiceTests {

   def trackerLogService

   private trackerId

   @Before
   void setUp(){    
      def tracker = new Tracker(name: "First")
      tracker.save()
      trackerId = tracker.id
   }

   @Test
   void testTrackerLogService() {
      Tacker trackerInstance  = Tracker.get(trackerId)

      String commit = "This is a commit" 

      //call the service
      Log log = trackerLogService.saveTrackerLogs(trackerInstance , commit)

      //want to make sure I added the log to the tracker Instance
      assertEquals log , trackerInstance.logs.findByCommit(commit)
   }
}

また、無関係idです。文字列などの非標準型でない限り、フィールドを宣言しないでください。Grailsは、フィールドとともにそれを追加しますversion。あなたに必要なのは

class Tracker {
   String name
   static hasMany = [logs: Log] 
}

class Log {
   String comment
   static belongsTo = [tracker: Tracker]
}
于 2012-07-17T18:46:34.633 に答える