Validate a single field in a Grails 3 Domain class

Sometimes you have a domain class with multiple fields and you would like to test a single constraint.

$ grails --version
Grails Version: 3.0.9

Create a Grails app test-app

$ grails create-app test-domain-validation
Generate a domain class
$ cd test-domain-validation
$ grails
grails>
grails> create-domain-class Person
| Created grails-app/domain/test/domain/class/validation/Person.groovy
| Created</code> src/test/groovy/test/domain/class/validation/PersonSpec.groovy

Add a firstName, lastName and age to the Person domain class

package test.domain.validation
class Person {
    String firstName
    String lastName
    Integer age
    static constraints = {
        age range: 0..120
    }
}

Add the next test to validate the age constraint:

@TestFor(Person)
class PersonSpec extends Specification {

    @Unroll('validate on a person with age #personAge should have returned #shouldBeValid')
    void "test age validation"() {
        expect:
        new Person(age: personAge).validate() == shouldBeValid
        
        where:
        personAge | shouldBeValid
        -2        | false
        -1        | false
        0         | true
        1         | true
        119       | true
        120       | true
        121       | false
        122       | false
    }
}

Test fails:

test.domain.validation.PersonSpec &gt; validate on a person with age 0 should have returned true FAILED
    org.spockframework.runtime.SpockComparisonFailure at PersonSpec.groovy:14

test.domain.validation.PersonSpec &gt; validate on a person with age 1 should have returned true FAILED
    org.spockframework.runtime.SpockComparisonFailure at PersonSpec.groovy:14

test.domain.validation.PersonSpec &gt; validate on a person with age 119 should have returned true FAILED
    org.spockframework.runtime.SpockComparisonFailure at PersonSpec.groovy:14

test.domain.validation.PersonSpec &gt; validate on a person with age 120 should have returned true FAILED
    org.spockframework.runtime.SpockComparisonFailure at PersonSpec.groovy:14

8 tests completed, 4 failed
:test FAILED

By default domain class’ fields have the constraint nullable: false. Validate() tries to validate all the fields and thus the validation fails.

However, we can pass to validate just the list of field names which we wish to validate in this particular test.

Thus replacing:

new Person(age: personAge).validate() == shouldBeValid

with:

new Person(age: personAge).validate(['age']) == shouldBeValid

makes the test pass.

I learn this thanks to the Jeff Scott Brown’s Testing with Grails 3 talk.

Do you like to read about Groovy/Grails development? Yes, then Subscribe to Groovy Calamari a weekly curated email newsletter about the Groovy ecosystem which I happen to write 😉

Leave a Reply

Your email address will not be published. Required fields are marked *