I recently worked on a Grails 2.5.0 application and I was making the wrong assumption that the matches constraint is checked against the domain property all the times so even when its value is blank or null.

The field constraint was defined similar to this:

username matches: '[.\\-\\w]+'

I was expecting the matches constraint to be verified on the username property value. The reality is that when the target property value is blank the matches constraint is never invoked and there are no errors registered. The AbstractConstraint#skipBlankValues() method returns true by default and MatchesConstraint doesn’t override it to return false:
Constrained property validation

To get an error reported for blank values you need to explicitly add the blank constraint:

username matches: '[.\\-\\w]+', blank: false

While unit testing the constrained property I got into a different issue. There is still an open bug in Grails related to unit testing. If you rely on grails.databinding.convertEmptyStringsToNull=false and grails.databinding.trimStrings = false you need to be aware they’re being ignored when running the unit tests. If you create your test fixture objects by means of the Map constructor Grails will populate your objects with null values for any blank Strings:

def user = new User(username: '   ')
assert user.username == null

There are several workarounds but the easiest is to avoid the data binding in the first place:

def user = new User()
user.username = '   '
assert user.username == '   '

Posted in Programming and tagged with Grails.