0

当我尝试使用 grails 动态 get 方法获取域对象时,我的 grails 应用程序的集成测试返回一个空对象。这是我的问题的简化示例。假设我有一个控制器TrackerLogController,它使用服务TrackerLogService为另一个Tracker域保存更新的日志域。域跟踪器:

class Tracker {

   int id
   String name

   static hasMany = [logs: Log] 
}

域日志:

class Log {
   int id
   String comment

   static belongsTo = [tracker: Tracker]
}

控制器 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 将是一个空对象。我知道 Grails 魔法似乎不适用于没有 Mocking 的单元测试,我认为对于数据库中的持久性的 Intigration-Tests,您将能够使用 Grails 魔法。

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 回答