2011-08-31 43 views
0

我有两个领域类这样的,第一即Manager似乎Groovy在这两种情况下行为不同?

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()) 
    } 

那么没有错误在它和测试通过!但是,当我添加更多的东西到像相同的测试(现在我想反,通过使用Project找到Manager名):

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() 

我哪里出错了?

在此先感谢。

回答

3

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

在第一次测试中,您不会重新加载manager实例,因为get()将Hibernate会话用作第一级缓存,所以仍然使用内存中的一个。如果冲洗,清除会话,迫使它去数据库会失败:因为你呼吁Project实例save()并在验证失败时返回null

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()) 
    } 
} 

第二个失败。您不需要保存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) 
+0

你能更多地解释你的意思通过“,默认情况下所有的属性都不是null,所以当你只设置了”projectTitle“时,你的Project实例就无法通过验证。 ? –

+0

验证?但是在我的领域类中,我根本没有做过任何类型的验证:/那么验证失败如何? –

+1

默认情况下,所有属性都是必需的。你可以用一个约束'nullable:true'来改变它。所以如果你创建一个新的'Project'并且只设置'projectTitle',你会得到'projectDescription'和'description'的验证错误。调用'save()'首先调用'validate()'以确保不会将无效数据推送到数据库。你可以明确地调用'validate()',但它也是为你完成的。 –

相关问题