看起来像Groovy在这两种情况下的行为不同?

时间:2011-08-31 11:10:03

标签: testing grails groovy integration-testing

我有两个这样的域类,首先是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 个答案:

答案 0 :(得分:3)

在这两种情况下你都有同样的问题,但第一种不是正确的测试,所以它似乎有效。问题是默认情况下所有属性都不为null,因此当您仅设置Project时,projectTitle个实例将无法通过验证。

在第一个测试中,您没有重新加载manager实例,您仍在使用内存中的那个,因为get()使用Hibernate会话作为第一级缓存。如果刷新并清除会话以强制它转到数据库,它将失败:

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并且在验证失败时返回null。您不需要保存Project个实例,因为当保存包含Manager时,它们将被传递保存 - 您在第一次测试中使用的标准模式就越多。

您有几个选择。一个是修复验证错误:)另一个是检查验证错误。这需要单独的save()调用,因此您可以访问非空实例:

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)