在Grails 3单元测试中使用GORM addTo方法

时间:2016-08-29 23:26:03

标签: unit-testing grails spock

我正在升级一系列在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交互的测试支持来存储该方法。

  3. 实际上,我已经尝试了几乎所有我能想到的组合,以便在没有运气的情况下使用它。我在最新的Grails规范中重新阅读了测试部分。

    这里有什么方法可以保持单元测试吗?

1 个答案:

答案 0 :(得分:-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)
 }