Defining and Testing Constraints on Grails Domain Classes
Defining constraints in Grails domain classes is achieved quite simply with a static property defined directly in the domain class. For example, I can define a User domain class and its constraints as follows:
class User {
String login
String password
String email
Integer age
static constraints = {
login(size: 5..15, blank: false, unique: true)
password(size: 5..15, blank: false)
email(email: true, blank: false)
age(min: 18, nullable: false)
}
}
Constraints are syntactically formatted as method calls with the name of the method matching the name of the property the constraint is to be associated with. The method parameters are named parameters specifying the constraint. On User we have defined a constraint for each property. This was my decision to constrain each property, there is not a requirement to name a constraint for all properties in a domain class.
So far so good, but now I want to verify my constraints work the way I expect. The easiest way to test constraints is as part of a unit test. Grails provides mocking support in unit tests, so to setup a mock domain class for constraint testing I would create the following test class.
import grails.test.*
class UserTests extends GrailsUnitTestCase {
protected void setUp() {
super.setUp()
mockForConstraintsTests(User)
}
protected void tearDown() {
super.tearDown()
}
void testValidation() {
defuser = newUser(login: 'jdoe', password: 'passw0rd', email: 'jdoe@foo.com', age: 32)
assertTrue user.validate()
}
}
That is it. One item of note, I recently found out that it is possible to pass a list of property names to the valdiate() method indicating that the validation should only be run on those properties. For example, if I only want to validate the login and password properties on an instance of User then I would do the following.
user.validate(['login','password'])
This trick, however, does not work in unit tests as it appears the validate method provided by the mock does not accept any parameters. Still, this will come in handy when I know that I don’t have a fully populated domain POGO, but want to validate what I have. Say, for example, in a UI wizard where each step sets a partial set of properties on the domain class.
Member discussion