Sunday, February 8, 2009

Unit testing: testing domain entity using Testing Plugin

In previous post we got acquainted with Grails Testing Plugin. In this post we will look closer how to write unit test for domain class, especially how to easily test its constraints. As far as I mentioned Testing Plugin includes a lot of mock*() methods for testing domain entities, controllers, tag libs, etc. One of such methods is mockForConstraintsTests() method which is very useful to check whether the constraints are behaving as you expect them to.
Suppose we have a simple domain class like so:

class User {

String email
String firstName
String lastName
String password

static constraints = {
email(email: true, unique: true, blank: false,
maxSize: 64)
firstName(blank: false, minSize: 2, maxSize: 32)
lastName(blank: false, minSize: 2, maxSize: 32)
password(blank: false, maxSize: 128)
}

String toString() {
"""User [email: ${email},
firstName: ${firstName},
lastName: ${lastName}]"""
}

}


To test these constraints we can do the following:

class UserTests extends GrailsUnitTestCase {

void testUserConstraints() {

// Assume that we have an existing user
// in the database.

def existingUser = new User(
email: "taras.matyashovsky@gmail.com",
firstName: "Taras",
lastName: "Matyashovsky",
password: "some hash")
// Using mockForConstraintsTests for mocking.
mockForConstraintsTests(User, [existingUser])


// Validation should fail if email or
// first name or last name or
// password properties are null.

def user = new User()
assert !user.validate()
assertEquals "nullable", user.errors["email"]
assertEquals "nullable", user.errors["firstName"]
assertEquals "nullable", user.errors["firstName"]
assertEquals "nullable", user.errors["password"]


// So let's demonstrate the unique
// and min size constraints.
// Insert user with the same email
// and very short first and last names.

user = new User(
email: "taras.matyashovsky@gmail.com",
firstName: "T",
lastName: "M",
password: "some hash")
assert !user.validate()
assertEquals "unique", user.errors["email"]
assertEquals "minSize", user.errors["firstName"]
assertEquals "minSize", user.errors["lastName"]


// So let's demonstrate the max size constraints.
// First name is too long (more than 32 symbols).

user = new User(
email: "grails-groovy@blogger.com",
firstName: "TarasTarasTarasTarasTarasTarasTaras",
lastName: "Matyashovsky",
password: "some hash")
assert !user.validate()
assertEquals "maxSize", user.errors["firstName"]


// Validation should pass.

user = new User(
email: "andriy.suran@gmail.com",
firstName: "Andriy",
lastName: "Suran",
password: "some hash")
assert user.validate()
}

}


Using errors property we can access all the properties and methods we should normally expect. We simply specify the name of the field we are interested in and the map/property access will return the name of the constraint that was violated. Testing Plugin makes testing easy.

No comments:

Post a Comment