Search

Dark theme | Light theme

January 25, 2010

Groovy Goodness: Create Stubs for Testing

We can write unit tests with Groovy by simply extending the GroovyTestCase class. In the test we can use the default Groovy classes MockFor and StubFor to create mocks and stubs for classes and interfaces. We can create a mock or stub for Groovy classes, but also for Java classes. Once we have a mock or stub we can execute the code we want to test in the context of the mock or stub with the use() method.

In this example we create a stub for a Groovy service class. We want to define our own return result for the method findLanguages(), so we can test the logic in the caller class.

import groovy.mock.interceptor.*

class CallServiceTest extends GroovyTestCase {
    def callService = new CallService()
    
    void testServiceCall() {
        def stub = new StubFor(MyService.class)
        stub.demand.findLanguages { ['Java', 'Groovy'] }  // Return one language with an 'a' and one without.
        stub.use {
            callService.myService = new MyService()
            def result = callService.findLanguagesWithA()  // Will use method from stub.
            assert 1 == result.size()
            assert 'Java' == result[0]
        }
    }
    
    void testEmptyResult() {
        def stub = new StubFor(MyService.class)
        stub.demand.findLanguages { ['Groovy', 'Clojure'] }  // Return no languages with an 'a'.
        stub.use {
            callService.myService = new MyService()
            def result = callService.findLanguagesWithA()  // Method from stub is invoked.
            assert !result
        }
    }
}

class CallService {
    def myService = new MyService()
    
    List findLanguagesWithA() {
        def languages = myService.findLanguages()
        languages.grep({ it.contains('a') })
    }
}
class MyService {
    List findLanguages() {
        // Get real data from database for example.
        // That is why we want to stub this class, so we don't rely on
        // the database.
        []
    }
}

January 24, 2010

Grails Goodness: Simple Script to Create WAR Files for Each Environment

We can create a new WAR file with the following Grails command:

$ grails test war dist/test.war

This will make a new WAR file in the dist directory with the name test.war. We use the test environments for the settings.

With the following Groovy script we create a WAR file in the dist for each environment. We use application.properties to get the application name and version and use it to create the WAR filename.

// File: createwar.groovy
// Run with: $ groovy createwar.groovy
def ant = new AntBuilder()

// Read properties.
ant.property file: 'application.properties'

def appVersion = ant.project.properties.'app.version'
def appName = ant.project.properties.'app.name'

def envs = ['dev', 'test', 'prod', 'testserver1', 'testserver2']
envs.each { env ->
    def grailsEnv = env
    ant.exec(executable: 'grails') {
        arg(value: "-Dgrails.env=${grailsEnv}")
        arg(value: 'war')
        arg(value: "dist/${appName}-${appVersion}-${grailsEnv}.war")
    }
}

January 23, 2010

Grails Goodness: Multiple Environments

Grails supports different environments for configuring properties. Default we get a development, test and production environment, but we are free to add our own environments. We can define the new environment in for example grails-app/conf/Config.groovy. Next we can use the environment from the command line with the -Dgrails.env= option. Here we must use our newly created environment.

// grails-app/conf/Config.groovy
environments {
    development { ws.endpoint = 'http://localhost/ws.wsdl' }
    test { ws.endpoint = 'http://test/ws.wsdl' }
    production { ws.endpoint = 'http://ws.server/complete/ws.wsdl' }
    testserver1 { ws.endpoint = 'http://testserver1/test/ws.wsdl' }
    testserver2 { ws.endpoint = 'http://testserver2/test/ws.wsdl' }
}

To create a new WAR file with the settings for the testserver2 environment we type the following command:

$ grails -Dgrails.env=testserver2 war

January 22, 2010

Groovy Goodness: Round and Truncate Decimal Values

Groovy adds round() and truncate() methods to the Double and Float classes.

def doubleValue = 12.5456d

assert 12.546d == doubleValue.round(3)
assert 13 == doubleValue.round()

assert 12 == doubleValue.trunc()
assert 12.54d == doubleValue.trunc(2)

def floatValue = 987.654f

assert 987.65f == floatValue.round(2)
assert 988 == floatValue.round()
assert 987.6f == floatValue.trunc(1)
assert 987 == floatValue.trunc()

January 21, 2010

Grails Goodness: Rerun the Latest Failed Test

We can test our Grails application with $ grails test-app. But if one or more test fail we can easily rerun only the failed tests with the following command:

$ grails test-app -rerun

January 19, 2010

Groovy Goodness: Integer Divisions

In Groovy we can use two methods to divide two integers. The div() will return the result as BigDecimal. And if we use the method intdiv() we get the result as Integer, because an integer division is done.

def x = 26
def y = 10

def resultDiv = x.div(y)  // or x / y
def resultIntDiv = x.intdiv(y)

assert 2.6 == resultDiv
assert 2 == resultIntDiv
assert java.math.BigDecimal == resultDiv.class
assert java.lang.Integer == resultIntDiv.class

January 18, 2010

Grails Goodness: Logging Service Method Calls with Dynamic Groovy

Because Grails is a Groovy web application framework we can use all the nice features of Groovy, like dynamic programming. Suppose we want to log all method invocation of Grails services. We have to look up the Grails services and override the invokeMethod() for the classes. Here we invoke the original method, but also add logging code so we can log when we enter and exit the method.

The best place to put our code is in grails-app/conf/BootStrap.groovy of our Grails application. Here we use the init closure to first look up the Grails service classes. Next we override the invokeMethod().

// File: grails-app/conf/BootStrap.groovy
class BootStrap {
    def grailsApplication

    def init = { ctx ->
        setupServiceLogging()
    }
    
    def destroy = { }
    
    private def setupServiceLogging() {
        grailsApplication.serviceClasses.each { serviceClass ->
            serviceClass.metaClass.invokeMethod = { name, args ->
                delegate.log.info "> Invoke $name in ${delegate.class.name}"
                def metaMethod = delegate.metaClass.getMetaMethod(name, args)
                try {
                    def result = metaMethod.invoke(delegate, args)
                    delegate.log.info "< Completed $name with result '$result'"
                    return result
                } catch (e) {
                    delegate.log.error "< Exception occurred in $name"
                    delegate.log.error "< Exception message: ${e.message}"
                    throw e
                }
            }
        }
    }
}

Groovy Goodness: Override getProperty Method with Dynamic Groovy

Groovy's ExpandoMetaClass features allows us to override the getProperty() method for a class. This method is invoked if we want to access a property for an object. We can look up existing properties and return their result, but we can also write behaviour for the situation when the property doesn't exist.

class User {
    String username
}

User.metaClass.getProperty = { String propName ->
    def meta = User.metaClass.getMetaProperty(propName)
    if (meta) {
        meta.getProperty(delegate)
    } else {
        'Dynamic property for User'
    }
}

def mrhaki = new User(username: 'mrhaki')
def hubert = new User(username: 'hubert')

assert 'mrhaki' == mrhaki.username
assert 'Dynamic property for User' == mrhaki.fullname

January 17, 2010

Groovy Goodness: Create Elements in Collection Definition

Small things can make our lives easier. For example if we use Groovy we can create a new list or map with a list of elements directly. We don't have to use an add() method.

def list = [
    'one', 
    'two', 
    'three',
]

def map = [
    'groovy': 1.7,
    'mrhaki': 'hubert',
]

assert list
assert map

January 16, 2010

Groovy Goodness: Apply Method to All Elements in a List

In Groovy we have several ways to achieve the same thing. For example we can apply a method to all elements in a list with the collect() method or with *..

class User { 
    String name 
    String aloud() { name.toUpperCase() }
    String toString() { name }
}

def users = [new User(name: 'mrhaki'), new User(name: 'hubert')]

assert ['mrhaki', 'hubert'] == users*.toString()
assert ['MRHAKI', 'HUBERT'] == users*.aloud()
assert ['mrhaki', 'hubert'] == users.collect { it.toString() }
assert ['MRHAKI', 'HUBERT'] == users.collect { it.aloud() }

January 15, 2010

Groovy Goodness: Is Object in Class Hierarchy

With Groovy's in keyword we can check if an object is assignable for a class in the class hierarchy (noted by Andrey Paramonov - see comment section). This way we can check if the object is an instance of a certain class or one of the parents of the class or to be more specific, if the class is assignable for the class or parent classes. This can also be useful when checking if an exception for example is part of an exception hierarchy.

class Shape { }
class Circle extends Shape { }
class Square extends Shape {}

// Create Square instance.
def square = new Square()

assert square in Shape
assert square in Square
assert !(square in Circle)

[Shape.class, Square.class].each {
    assert square in it
}

January 14, 2010

Grails Goodness: Access Grails Application in BootStrap

Accessing the Grails application object in BootStrap.groovy is easy. We only have to define a variable named grailsApplication and Spring's name based injection takes care of everything.

class BootStrap {
    // Reference to Grails application.
    def grailsApplication

    def init = { servletContext ->
        // Access Grails application properties.
        grailsApplication.serviceClasses.each {
            println it 
        } 
    }

    def destroy = {}
}

Running VisualVM with Mac OSX

Coming from a Windows environment I was used to run visualvm.exe for VisualVM. In Mac OSX we must use jvisualvm to run VisualVM.

January 8, 2010

Busy Times

This week has been a hectic week. I started at a new employer (VX Company) and at a new project. Because of the transition (and no personal laptop yet) and didn't get a change to publish a daily Groovy Goodness post. I promise I will continue once all settles down, which will be at the start of next week.

January 5, 2010

Groovy Goodness: Make a Number Absolute

In Groovy we can make a number absolute with the abs() method. This method is added to the Number class by Groovy.

assert 42 == (-42).abs()
assert 43.21 == (-43.21).abs()

Groovy Goodness: Add a ShutdownHook

If we want to execute some code when our Groovy script or application is stopped we can use the addShutdownHook() method. We pass a closure to this method, which is executed when our Groovy script or application stops. This can be a normal termination, but the closure is also executed when the application is stopped by user input (Ctrl+C) or a system event like a shutdown.

addShutdownHook {
    println ''  
    println 'Script is ended.'
}

println 'Script is started.'
println 'Press Ctrl+C to stop this script or wait 10 seconds.'
(1..10).each {
    print "..$it"
    Thread.sleep 1000
}

January 4, 2010

Groovy Goodness: Turn a List into a Map

With Groovy we can use the values of an Object array and transform them to a map with the toSpreadMap() method. The array must have an even number of elements, because the odd elements are the keys for the new map and the even numbers are the values for the keys. The SpreadMap object, which now contains the keys and values, is an immutable map, so we cannot change the contents once we have created the map.

def list = ['key', 'value', 'name', 'mrhaki'] as Object[]
def map = list.toSpreadMap()

assert 2 == map.size()
assert 'value' == map.key
assert 'mrhaki' == map['name']

January 3, 2010

Groovy Goodness: Check if String is a Number

Groovy adds several methods to the String class to see if the string value is a number. We can check for all kind of number type like Integer, Double, BigDecimal and more.

assert '42'.isNumber()
assert '42'.isInteger() && '42'.isLong() && '42'.isBigInteger()
assert '42.42'.isDouble() && /42.42/.isBigDecimal() && '42.42'.isFloat()

January 2, 2010

Groovy Goodness: Normalize and Denormalize Linefeeds and Carriage Returns

Each platform where we can run Java and Groovy applications has different line separators. Groovy adds two methods to the String class to convert the specific platform line separator to linefeeds and vica versa.

def text = 'First line\r\nSecond line\r\n'
def textNormalized = text.normalize()
def platformLineSeparator = System.properties['line.separator']

assert 'First line\nSecond line\n' == textNormalized
assert "First line${platformLineSeparator}Second line${platformLineSeparator}" == textNormalized.denormalize()

January 1, 2010

Groovy Goodness: Removing Duplicate Elements in a Collection

We can easily remove duplicate elements in a collection with the different unique() methods. Without any parameters the default comparator for the objects is used to determine duplicate elements. But we can also use a closure to define the rules for duplicate elements. The closure can have one parameter and then we must return a value that is used for comparison, or the closure has two parameters and then we must return an Integer value where 0 means the items are not unique. Finally we can pass our own Comparator implementation to the unique() method where we define when an element is unique or not.

class User implements Comparable {
    String username, email
    boolean active
    
    int compareTo(Object other) {
        username <=> other.username
    }
}

def mrhaki1 = new User(username: 'mrhaki', email: 'mrhaki@localhost', active: false)
def mrhaki2 = new User(username: 'mrhaki', email: 'user@localhost', active: true)
def hubert1 = new User(username: 'hubert', email: 'user@localhost', active: false)
def hubert2 = new User(username: 'hubert', email: 'hubert@localhost', active: true)

// Caution: unique() changes the original collection, so 
// for the sample we invoke unique each time on a fresh new
// user list.
def uniqueUsers = [mrhaki1, mrhaki2, hubert1, hubert2].unique()
assert 2 == uniqueUsers.size()
assert [mrhaki1, hubert1] == uniqueUsers

// Use closure with one parameter.
def uniqueEmail = [mrhaki1, mrhaki2, hubert1, hubert2].unique { user -> 
    user.email 
}
assert 3 == uniqueEmail.size()
assert [mrhaki1, mrhaki2, hubert2] == uniqueEmail

// Use closure with two parameters.
def uniqueActive = [mrhaki1, mrhaki2, hubert1, hubert2].unique { user1, user2 ->
    user1.active <=> user2.active
}
assert 2 == uniqueActive.size()
assert [mrhaki1, mrhaki2] == uniqueActive

// Use a comparator.
def emailComparator = [
    equals: { delegate.equals(it) },
    compare: { first, second ->
        first.email <=> second.email
    }
] as Comparator
def unique = [mrhaki1, mrhaki2, hubert1, hubert2].unique(emailComparator)
assert 3 == unique.size()
assert [mrhaki1, mrhaki2, hubert2] == unique
​