Testing reusable validation
In the application we are developing, a lot of input validation takes place. Most of the input is validated using Command Objects, which are a breeze to use thanks to Grails’ fantastic way of integrating them. However, in some of our Command Objects, there’s some overlap, most notably in the validation part. For example, we use a CreateCustomerCommand and a OrderProductCommand, which both have a ‘zipcode’ field, which, in our case, matches the regular expression [0-9]{4}[a-zA-Z]{2}. Since we don’t want to duplicate this regular expression, we need to come up with a solution to be able to reuse this.
One way of accomplishing this is to use Grails Global Constraints. Grails Global Constraints allow you to define your Constraints once, and reuse them in your application. However, (IMO) there are some downsides to this technique. One of them is testing these validations. I still haven’t found a way to Unit test these validations, even though I spent quite some time looking into a way to accomplish this. Another downside is that these validations are in the Config.groovy, which pollutes your configuration with application logic. Not the best way to accomplish this.
The alternative way, which is the way we are using, is to create something simple ourselves. We created a SharedConstraints class, which contains all the shared validations in our application. A small example:
class SharedConstraints {
static def simCardNumber = [
blank: false,
validator:{ val, cmd ->
val ==~ /[1-9][0-9]{7}/
}]
}
To use this, do the following:
class NewSimCardCommand {
String simCardNumber
static constraints = {
simCardNumber(SharedConstraints.simCardNumber)
}
}
The only thing left is testing this. To test the simcard number validation in isolation, we use the following code:
class SharedConstraintsTest extends GrailsUnitTestCase {
void testSimCardNumber() {
setupConstraint(SharedConstraints.simCardNumber)
assert !checkConstraint("abcdef")
assert !checkConstraint("02345678")
assert checkConstraint("12345678")
}
private void setupConstraint(def constraint) {
ObjectToValidate.constraints = {
validatableField(constraint)
}
mockForConstraintsTests(ObjectToValidate)
}
private boolean checkConstraint(def inputValue) {
return new ObjectToValidate(validatableField: inputValue).validate()
}
static class ObjectToValidate {
def validatableField
static constraints // this is the constraints block which will emulate Grails validation
}
}
Creating this simple infrastructure class enables you to easily test constraints, which can be reused in all commands or domain objects.

We have use the constraints plugin on our projects. This works also very well. Constraints are handled as Grails artifacts, can be re-used in command objects/domain classes and they are easy to unit test. See https://github.com/geofflane/grails-constraints
Hi Hubert, thanks for the reply. I wasn’t aware of this plugin, but I’ll check it out and see how it compares to our current method. Thanks for the tip!
Hi Erik!
Thank you for this cool approach. I tried your approach, but having a problem when I want do have more than one custom constraint on a field:
static constraints = {
name(SharedConstraints.checkA, SharedConstraints.checkB)
}
As I’m pretty new to grails I don’t if this is possible?
Anyway, do you still use this approach or you switched to contraints plugin?
Thank you very much!
Zoran F., I’m pretty sure there is a grails limitation in 1.x that you can only have 1 custom constraint per field. If you need multiple, you have to make a new custom constraint that encompasses the others. I know, annoying. Not sure if 2.0 addresses this or not.
I just got the answer yesterday in grails forum. It should be “+” instead of “,”.
static constraints = {
name(SharedConstraints.checkA + SharedConstraints.checkB)
}
http://grails.1312388.n4.nabble.com/how-to-use-several-shared-reusable-constraints-on-a-field-td3815020.html#none
Thank you
Hi Zoran, thanks for sharing this information!
Erik.