我确定这个问题已经被回答过了,但是在文档或其他地方找不到。 我如何(单元?)在grails域模型类中测试关联?
例如,如果我有以下课程:
class StudentClass {
static hasMany = [students: Student]
static mapping = {
students cascade: "none"
}
}
class Student {
String name
static belongsTo = [studentClass: StudentClass]
}
如何测试“ hasMany”及其层叠?
编辑:
换句话说,我想测试将此配置添加到模型中的效果,以确保它满足我的需求。
例如,我希望能够做类似的事情(假设我了解关联文档;可以将其更改为更好的测试或在出错时进行修复)
def sc = new StudentClass().save()
new Student(studentClass: sc, name: 'name1').save()
assert StudentClass.count() == 1
assert StudentClass.get(1).students.size() == 1
assert StudentClass.get(1).get(0).name == 'name'
StudentClass.delete(1)
assert Student.count() == 1
谢谢
答案 0 :(得分:0)
最近,我试图了解级联更新和删除在GORM中是如何工作的,并遇到了您的问题。在遇到用于测试一对多关系的单元测试问题之后,我对Grails的闲置通道提出了一个问题,有人建议我们可以创建一个集成测试,因为级联可能不适合与单元测试一起运行。
让我们如下创建域类。
SchoolClass.groovy
package com.itersdesktop.javatechs.grails.gorm
class SchoolClass implements Serializable{
// for example: Class 1 or Owl class
String name
// year 1, year 2, etc.
Integer year
// for example: 2018-2019
String schoolYear
// there are at least two teachers: main and assistant
static hasMany = [teachers: SchoolTeacher, pupils: Pupil]
static mapping = {
teachers cascade: 'all-delete-orphan'
pupils cascade: 'all-delete-orphan'
}
static constraints = {
}
}
SchoolTeacher.groovy
package com.itersdesktop.javatechs.grails.gorm
class SchoolTeacher implements Serializable {
String name
static belongsTo = [schoolClass: SchoolClass]
static constraints = {
}
}
学生班
package com.itersdesktop.javatechs.grails.gorm
class Pupil implements Serializable {
String name
static belongsTo = [schoolClass: SchoolClass]
static constraints = {
}
}
如您所见,SchoolClass
具有teachers
和pupils
属性,可以在其上设置更新和删除级联。我们要验证的是,只要销毁了学校课程实例,学生就会自动被移除。为此,我分别进行了名为SchoolClassSpec.groovy
和SchoolClassItSpec
的单元测试和集成测试。
SchoolClassSpec.groovy
package com.itersdesktop.javatechs.grails.gorm
import grails.testing.gorm.DomainUnitTest
import spock.lang.Specification
class SchoolClassSpec extends Specification implements DomainUnitTest<SchoolClass> {
SchoolClass schoolClass
Pupil p
void setupData() {
schoolClass = new SchoolClass(name: "Owl class", year: 2, schoolYear: "2017-2018")
p = new Pupil(name: "Tony Nguyen")
schoolClass.addToPupils(p)
}
void "test SchoolClass domain"() {
given: "let's create a school class and a pupil"
setupData()
when: "save the school class"
schoolClass.save()
then: "we also save the pupil because we set cascade on SchoolClass"
1 == SchoolClass.count
1 == Pupil.count
when: "get the school class and the pupil back"
p = Pupil.get(1)
schoolClass = SchoolClass.get(1)
then: "we hope the returned values match with the inputs"
p.name == "Tony Nguyen"
schoolClass.name == "Owl class"
schoolClass.schoolYear == "2017-2018"
when: "let's delete the school class"
schoolClass.delete(flush: true)
then: "we hope the pupil will be deleted as well"
0 == SchoolClass.count
1 == Pupil.count
}
}
注意:最后一行1 == Pupil.count
是因为如果我们测试0 == Pupil.count
,则测试将失败。 Spock-Reports插件生成的测试报告类似于以下屏幕截图。
让我们使用上面相同的代码,但是要进行如下所述的集成测试。
SchoolClassItSpec.groovy
package com.itersdesktop.javatechs.grails.gorm
import grails.testing.mixin.integration.Integration
import grails.transaction.Rollback
import spock.lang.Specification
@Integration
@Rollback
class SchoolClassItSpec extends Specification {
SchoolClass schoolClass
Pupil p
void setupData() {
schoolClass = new SchoolClass(name: "Owl class", year: 2, schoolYear: "2017-2018")
p = new Pupil(name: "Tony Nguyen")
schoolClass.addToPupils(p)
}
void "test SchoolClass domain"() {
given: "let's create a school class and a pupil"
/*SchoolClass schoolClass = new SchoolClass(name: "Owl class", year: 2, schoolYear: "2017-2018")
Pupil p = new Pupil(name: "Tony Nguyen")
schoolClass.addToPupils(p)*/
setupData()
when: "save the school class"
schoolClass.save()
then: "we also save the pupil because we set cascade on SchoolClass"
1 == SchoolClass.count
1 == Pupil.count
when: "get the school class and the pupil back"
p = Pupil.get(1)
schoolClass = SchoolClass.get(1)
then: "we hope the returned values match with the inputs"
p.name == "Tony Nguyen"
schoolClass.name == "Owl class"
schoolClass.schoolYear == "2017-2018"
when: "let's delete the school class"
schoolClass.delete(flush: true)
then: "we hope the pupil will be deleted as well"
0 == SchoolClass.count
0 == Pupil.count
}
}
讨论 我们可以从测试中得出的结论是: