lundi 29 août 2016

Using GORM addTo methods in Grails 3 unit test

I am upgrading a series of unit tests that worked in Grails 2 to Grails 3 and having problems with domain tests that use GORM dynamic methods -- specifically the addTo{myHasMany} methods.

Given the following domain objects

class Contact {
  static hasMany = [ emails: ContactEmail ]

  void addEmail(ContactEmail email) {
    //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 ]
}

Then the following test case is failing in Grails 3 with an exception generated from the missing addToEmails() method referenced in the addEmail() method in Contact.

@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"
  }
}

What I have tried:

  1. I tried mocking the Contact instance using the DomainClassUnitTestMixin and the mockDomain() method to generate an instance with the GORM methods (or a subset) generated.

  2. I have tried stubbing the method using the Spock Interaction Based Testing support.

Actually, I've tried just about every combination that I can think of to get this to work without any luck. I've reread the testing section in the latest Grails spec.

Is there any way forward here and keeping it a unit test?

Aucun commentaire:

Enregistrer un commentaire