0

我正在尝试使用抽象类定义 Grails 域模型。我需要定义两个彼此具有一对一双向关系并且不能使它们工作的抽象类。

基于文档的 Face-Nose 示例的解释:

我实现了该示例并编写了一个按预期工作的测试:如果我设置关系的一端,grails 设置另一端。

class Face {
    static hasOne = [nose:Nose]

    static constraints = {
        nose nullable: true, unique:true
    }
}

class Nose {
    Face face
    static belongsTo = [Face]

    static constraints = {
        face nullable:true
    }
}


    when:'set a nose on the face'
        def testFace = new Face().save()
        def testNose = new Nose().save()

        testFace.nose = testNose
        testFace.save()

    then: 'bidirectional relationship'
        testFace.nose == testNose
        testNose.face == testFace

如果我将这两个类声明为抽象类并使用两个具体子类(没有任何属性的 ConcreteFace 和 ConcreteNose)重复相同的测试,则第二个断言为假:testNose.face 为空。

我做错了吗?如果不是,我如何分解抽象域类中的关系?

4

1 回答 1

0

你的 save() 比需要的多,而且 Nose 内部的逻辑是错误的。首先,Face类是好的;让我们在这里粘贴完成:

class Face {

   static hasOne = [nose:Nose]

   static constraints = {
      nose nullable:true, unique: true
   }
}

接下来,鼻子

class Nose {

   static belongsTo = [face:Face]

   static constraints = {
   }
}

在此请注意,一旦您拥有了belongsTo关系,您就不能在约束部分中让face(父级)为空。

最后,您的集成测试。确保它是一个集成测试,而不仅仅是一个单元测试。当您测试与数据库相关的逻辑(CRUD 操作)时,需要进行集成测试,而不仅仅是模拟单元测试所做的操作。这里:

def "test bidirectionality integration"() {
   given: "a fresh face and nose"
   def face = new Face()
   def nose = new Nose(face:face)
   face.setNose(nose)

   when: "the fresh organs are saved"
   face.save()

   then: "bidirectionality is achieved"
   face.nose == nose
   nose.face == face
}

请注意,即使保存鼻子也不需要,保存面子已经存在鼻子。您可以在face.save()之后添加语句nose.save( ),这将在这里给您任何东西,但在此之前不会给您任何东西——在它的父母很好地安顿在您的桌子上之前,您无法保存孩子。

这样做,你会得到其中之一:

|Tests PASSED - view reports in ...
于 2015-05-11T15:27:14.180 回答