看起来 Groovy 在这两种情况下的行为有所不同?
我有两个这样的域类,第一个是 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 = {
}
}
我编写了这样的集成测试(以查找 的名称)项目
(通过使用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()
我哪里错了?
提前致谢。
I have two domain classes like this, first namely Manager
:
package com.mnm
class Manager {
String name;
static hasMany = [ project : Project, tasks : Tasks ]
static constraints = {
}
}
And second one namely, Project
:
package com.mnm
class Project {
String projectTitle
String projectDescription
String description
static belongsTo = [ managers: Manager ]
static hasMany = [ tasks : Tasks ]
static constraints = {
}
}
And I wrote Integration test like this (to find the name of the projects
via using 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())
}
Well there is no error in it and the test passes! But when I add more stuffs into to the same test like (now I'm trying the reverse, finding the Manager
name via using 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)
}
Now I get the error like this :
No signature of method: com.mnm.Manager.addToProject() is applicable for argument types: (null) values: [null] Possible solutions: addToProject(java.lang.Object), getProject()
Where I went wrong?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这两种情况下您都遇到相同的问题,但第一个不是正确的测试,因此它似乎有效。问题是默认情况下所有属性都不为 null,因此当您仅设置
projectTitle
时,您的Project
实例将无法验证。在第一个测试中,您不重新加载
manager
实例,您仍在使用内存中的实例,因为get()
使用 Hibernate 会话作为第一个级缓存。如果您刷新并清除会话以强制其转到数据库,它将失败:第二个失败,因为您在
Project
实例上调用save()
并且它返回验证失败时为 null。您不需要保存Project
实例,因为它们将在保存包含的Manager
时被传递保存 - 更标准的模式是您在第一个测试中使用的模式。你有几个选择。一种是修复验证错误:)另一种是检查验证错误。这需要单独的
save()
调用,以便您可以访问非空实例:第三个是
failOnError
,它将在验证失败时抛出异常:You have the same problem in both cases, but the first isn't a proper test so it seems to work. The issue is that all properties are not-null by default, so your
Project
instances fail validation when you only setprojectTitle
.In the first test you don't re-load the
manager
instance, you're still using the one in-memory becauseget()
uses the Hibernate session as a 1st-level cache. If you flush and clear the session to force it to go to the database it will fail:The second one fails because you call
save()
on theProject
instance and it returns null when validation fails. You don't need to saveProject
instances because they will be transitively saved when the containingManager
gets saved - the more standard pattern is the one you use in the first test.You have a few options. One is to fix the validation errors :) Another is to check for validation errors. This requires a separate
save()
call so you have access to the not-null instance:The third is
failOnError
which will throw an exception when validation fails: