【问题标题】:Using GORM addTo methods in Grails 3 unit test在 Grails 3 单元测试中使用 GORM addTo 方法
【发布时间】:2016-08-29 23:26:02
【问题描述】:

我正在将在 Grails 2 中运行的一系列单元测试升级到 Grails 3,并且在使用 GORM 动态方法(特别是 addTo{myHasMany} 方法)的域测试中遇到问题。

给定以下域对象

class Contact {
  static hasMany = [ emails: ContactEmail ]

  void addEmail(ContactEmail newEmail) {

    //Clear the existing primary flag if the new email is marked primary
    if (newEmail.primaryEmail == true) {
        for (ContactEmail contactEmail in this.emails) {
            if (contactEmail.primaryEmail == true) {
                contactEmail.primaryEmail = false
            }
        }
    }

    //Implicitly set the primary flag on the new email if it is the first in the list
    if ((this.emails == null) || (this.emails.size() == 0)) {
        newEmail.primaryEmail = true
    }

    //Add the email to the contact
    this.addToEmails(newEmail)
  }

}

class ContactEmail {
  String email
  Boolean primaryEmail

  static belongsTo = [ contact: Contact ]
}

然后,以下测试用例在 Grails 3 中失败,并从 Contact 中的 addEmail() 方法中引用的缺少的 addToEmails() 方法生成异常。

@TestMixin(DomainClassUnitTestMixin)
@TestFor(Contact)
class ContactSpec {

  def setup() {
  }

  def cleanup() {
  }

  @Unroll
  void "test Contact addEmail()"() {
    when:
    Contact contact = new Contact()
    ContactEmail contactEmail = new ContactEmail(email: "test@spiekerpoint.com", primaryEmail: false)
    contact.addEmail(contactEmail)

    then:       
    /* DOC - The add email without any other emails should implicitly set the primary email */
    contact.primaryEmail.toString() == "test@spiekerpoint.com"
  }
}

我尝试过的:

  1. 我尝试使用 DomainClassUnitTestMixin 和 mockDomain() 方法模拟 Contact 实例,以使用生成的 GORM 方法(或子集)生成一个实例。

  2. 我已尝试使用 Spock 基于交互的测试支持对方法进行存根。

实际上,我已经尝试了几乎所有我能想到的组合来让它工作,但没有任何运气。我重新阅读了最新 Grails 规范中的测试部分。

这里有什么方法可以继续进行单元测试吗?

【问题讨论】:

  • 我编辑了代码以修复联系人域对象中“newEmail”的类型。
  • 我随后重组了域代码和测试以在服务中运行,并且一切都按预期工作。该问题似乎完全限于域测试中的域对象。我不经常这样做,并且有一种观点认为这种逻辑无论如何都应该在服务中。在域中拥有这个有“鸡和蛋”的味道。

标签: unit-testing grails spock


【解决方案1】:

我没有看到newEmail在您的方法中的任何地方被初始化。所以你的 addToEmails() 失败了,因为 null 参数正在被传递。我认为您希望您的方法声明如下。

void addEmail(ContactEmail newEmail) {
//Clear the existing primary flag if the new email is marked primary
if (newEmail.primaryEmail == true) {
    for (ContactEmail contactEmail in this.emails) {
        if (contactEmail.primaryEmail == true) {
            contactEmail.primaryEmail = false
        }
    }
}

//Implicitly set the primary flag on the new email if it is the first in the list
if ((this.emails == null) || (this.emails.size() == 0)) {
    newEmail.primaryEmail = true
}

//Add the email to the contact
this.addToEmails(newEmail)
 }

【讨论】:

  • 我编辑了原始帖子以修复错字。然而,这不是问题——这只是问题中代码示例中的一个错字。失败是因为动态注入的 addTo{blah} 方法在域测试中不可用。无论我使用什么 mixin,这似乎都会发生……尽管我计划再次尝试 Hibernate mixin,因为我可能没有正确设置它。请参阅我对有关 testFor(service) 的原始帖子的附加评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多