Похоже, Groovy действует по-разному в этих двух сценариях? - PullRequest
0 голосов
/ 31 августа 2011

У меня есть два класса доменов, таких как первый, а именно: Manager:

package com.mnm

class Manager {
    String name;
    static hasMany = [ project : Project, tasks : Tasks ]
    static constraints = {
    }
}

И второй, а именно: Project:

package com.mnm

class Project {
    String projectTitle
    String projectDescription
    String description 
    static belongsTo = [ managers: Manager ]
    static hasMany = [ tasks : Tasks ]
    static constraints = {
    }
}

это (чтобы найти имя projects с помощью Manager):

 void testCountProject() {
        def manager = new Manager(name:'Anto').save()
        manager.addToProject(new Project(projectTitle:'Grails'))
        manager.addToProject(new Project(projectTitle:'Griffon'))
        def noOfProjects = Manager.get(manager.id)
        def found = noOfProjects.project.collect { it.projectTitle }
        assertEquals(['Grails','Griffon'], found.sort())
    }

Ну, в этом нет ошибки, и тест пройден!Но когда я добавляю больше материалов в один и тот же тест, например (сейчас я пытаюсь выполнить обратное, находя имя Manager с помощью Project):

 void testCountProject() {
        def manager = new Manager(name:'Anto').save()
        def project1 = new Project(projectTitle:'Grails').save()
        manager.addToProject(project1)
        manager.addToProject(new Project(projectTitle:'Griffon'))
        def noOfProjects = Manager.get(manager.id)
        def found = noOfProjects.project.collect { it.projectTitle }
        assertEquals(['Grails','Griffon'], found.sort())
        def noOfManager = Project.get(project.id)
        def foundManager = noOfManager.managers.collect { it.name }
        assertEquals(['Anto'],foundManager)
    }

Теперь я получаю ошибку, подобную этой:

No signature of method: com.mnm.Manager.addToProject() is applicable for argument types: (null) values: [null] Possible solutions: addToProject(java.lang.Object), getProject()

Где я ошибся?

Заранее спасибо.

1 Ответ

3 голосов
/ 31 августа 2011

У вас одна и та же проблема в обоих случаях, но первый не является подходящим тестом, поэтому, похоже, он работает. Проблема заключается в том, что все свойства не равны NULL по умолчанию, поэтому ваши Project экземпляры не проходят проверку, когда вы устанавливаете только projectTitle.

В первом тесте вы не перезагружаете экземпляр manager, вы все еще используете один в памяти, потому что get() использует сеанс Hibernate в качестве кэша 1-го уровня. Если вы очистите и очистите сеанс, чтобы заставить его перейти в базу данных, произойдет сбой:

class MyTest extends GroovyTestCase {

   def sessionFactory

   void testCountProject() {
      def manager = new Manager(name:'Anto')
      manager.addToProject(new Project(projectTitle:'Grails'))
      manager.addToProject(new Project(projectTitle:'Griffon'))
      manager.save(flush: true)

      sessionFactory.currentSession.clear()

      def noOfProjects = Manager.get(manager.id)
      def found = noOfProjects.project.collect { it.projectTitle }
      assertEquals(['Grails','Griffon'], found.sort())
   }
}

Второй сбой, потому что вы вызываете save() для экземпляра Project, и он возвращает ноль, если проверка не пройдена. Вам не нужно сохранять Project экземпляры, потому что они будут транзитивно сохранены при сохранении содержащего Manager - более стандартный шаблон - тот, который вы используете в первом тесте.

У вас есть несколько вариантов. Один из них - исправить ошибки проверки :) Другой - проверить ошибки проверки. Для этого требуется отдельный вызов save(), поэтому у вас есть доступ к экземпляру not-null:

def project1 = new Project(projectTitle:'Grails')
project1.save()
if (project1.hasErrors()) {
   // handle errors
}
else {
   manager.addToProject(project1)
}

Третье - failOnError, которое выдает исключение при сбое проверки:

def project1 = new Project(projectTitle:'Grails').save(failOnError: true)
manager.addToProject(project1)
...