Archive of articles classified as' "unit testing"

Back home

Upgrading to Grails 2 Unit Testing

2012/05/1

Grails 2 has a lot of great new unit testing features that make many test scenarios easier.

The grails documentation does an OK job of describing some of the new features, but there really wasn’t anywhere that I could find that had a comprehensive list of changes you should make to your code when migrating from grails 1.3.X to 2.0.X.

This blog post is the list of changes that I wished I had when I started to migrate our code. Read the rest of this article »

5 Comments

Creating New Instances of Spring “Singleton” Beans with Grails BeanBuilder

2011/03/7

When I’m integration testing Grails service classes, I often want to mock off a part of the class so that a complicated code branch isn’t followed that I’m not trying to test.

Grails will helpfully inject fully autowired Spring service beans into my test if I ask for them. Unfortunately, if I change the metaClass of the injected service, that change persists beyond where we want it to:

class MyService {
    def myMethod() { "unmodified" }
}
 
class MyServiceTests extends GroovyTestCase {
    def myService  // injected automatically by spring/grails
 
    void testOne() {
        myService.metaClass.myMethod = {-> "modified" }
        assertEquals "modified", myService.myMethod()
    } 
 
    void testTwo() {
        assertEquals  "unmodified", myService.myMethod() // WTF!  Returns "modified", pollution from first test
    }
}

Grails services are Spring “singleton” objects. They’re not true singletons though, singleton’s are just cached in the application context and returned whenever getBean is called.

Historically, if I wanted to mock part of my service manually, I’d need to “new” up my own instance of the service and manually inject any dependencies that the service might need to function. This is both painful and fragile, if the service adds or removes dependencies, chances are that the tests are going to break.

I realized that if I could ask Grails/Spring for a new instance of the “singleton” service that I could muck with it all I wanted in my test without worrying about polluting other tests with my changes. After some digging into the grails spring support, I came up with the following method that could be added to an integration test (or integration test base class):

// spring "singleton" objects really aren't they're just cached by their application context
def getNewSingletonInstanceOf(Class clazz) {
    String beanName = "prototype${clazz.name}"
    BeanBuilder beanBuilder = new BeanBuilder(ApplicationHolder.application.mainContext)
 
    beanBuilder.beans {
        "$beanName"(clazz) { bean ->
            bean.autowire = 'byName'
        }
    }
 
    beanBuilder.createApplicationContext().getBean(beanName)
}

This method uses the BeanBuilder to construct a temporary ApplicationContext with the Grails mainContext as a parent so that other dependencies can be resolved. This method won’t work if your service has changes to how it’s wired up and configured by spring, but the majority of Grails service classes are simply autowired byName.

Here’s a more detailed example of use. Given this service:

package com.example
 
class MyService {
    def injectedService
 
    def serviceMethod() {
        return otherMethod()
    }
 
    def otherMethod() {
        return "original value"
    }
}

I’m able to generate per-test autowired instances of my service and mock out otherMethod without polluting other tests (or the Spring injected version of the bean):

package com.example
 
import grails.spring.BeanBuilder
import org.codehaus.groovy.grails.commons.ApplicationHolder
 
class MyServiceTests extends GroovyTestCase {
    def myServiceInstance  // our new
    def myService // spring injected version
 
    protected void setUp() {
        super.setUp()
        myServiceInstance = getNewSingletonInstanceOf(MyService)
    }
 
    protected void tearDown() {
        super.tearDown()
    }
 
    // spring "singleton" objects really aren't they're just cached by their application context
    def getNewSingletonInstanceOf(Class clazz) {
        String beanName = "prototype${clazz.name}"
        BeanBuilder beanBuilder = new BeanBuilder(ApplicationHolder.application.mainContext)
 
        beanBuilder.beans {
            "$beanName"(clazz) { bean ->
                bean.autowire = 'byName'
            }
        }
 
        beanBuilder.createApplicationContext().getBean(beanName)
    }
 
    void testNewSingletonInstance() {
        assertNotNull myServiceInstance // created uniquely for this test in setUp
        assertNotNull myService         // spring injected into integration test
 
        assertNotSame myService, myServiceInstance
 
        // we've got unique instances of MyService, but both are injected with the same singleton dependencies
        assertSame myService.injectedService, myServiceInstance.injectedService
    }
 
    void testMessingWithMetaClassDoesNotAffectOriginalSingleton() {
        myServiceInstance.metaClass.otherMethod = {-> "new value" }
 
        assertEquals "new value", myServiceInstance.serviceMethod()
        assertEquals "original value", myService.serviceMethod()
 
        def anotherInstance = getNewSingletonInstanceOf(MyService)
 
        assertEquals "original value", anotherInstance.serviceMethod()
    }
}

Using this technique lets you leverage Spring’s autowiring in your tests, but also gives you the flexibility to override areas not under test to improve test readability and maintainability.

6 Comments

Adding Logging around all of the Methods of a Class with Groovy

2010/09/11

An interesting question came up on stack overflow, “In Groovy Is there a way to decorate every class to add tracing”. I came up with the following solution using groovy’s invokeMethod.

The invokeMethod method gets called by groovy’s MOP for every method call that happens on an object. If we add our own version, we need to make sure we keep a reference to the original metaClass so that within our invokeMethod, we can still get access to the other methods that we want to delegate to.

class Foo {
    def bar() {
        println "in bar"
    }
 
    def baz(String name) {
        println "in baz with $name"
    }
}
 
 
 
def decorateMethodsWithLogging(clazz) {
    def mc = clazz.metaClass
 
    mc.invokeMethod = { String name, args ->
        println "before $name, args = $args"
        def result = mc.getMetaMethod(name, args).invoke(delegate, args)
        println "after $name"
        return result
    }
}
 
 
decorateMethodsWithLogging(Foo.class)
 
def f = new Foo()
f.bar()
f.baz("qux")

prints

before bar, args = []
in bar
after bar
before baz, args = [qux]
in baz with qux
after baz
6 Comments

Running Grails Unit and Integration Tests in Parallel

2010/08/26

The number of tests on my current project is getting close to the 2000 mark (1504 unit and 351 integration) and running the full suite can take 4+ minutes to execute.

When you’re trying to do TDD and want to run all tests before pushing your code out to the shared repository, this length of time can really bog you down when it happens a number of times per day.

There are a number of tests that we need to go back in and refactor to be faster, but I wanted to see how much of a boost I could get by running unit and integration tests in parallel.

With 2 threads (one for unit, one for integration) the best case would be taking 50% of the time that it takes to run serially. That would only happen if my unit and integration tests took the same amount of time to run. For my tests, I was able to get a 39% speed improvement (with the integration tests taking a bit longer than the unit tests).

Here’s the script:
Read the rest of this article »

9 Comments

Grails Testing Alias to Rerun Failed Tests

2009/11/3

A while ago I blogged about my grails testing aliases and how much time they save me.

I’ve made some enhancements to them in the interim that have made them even easier to use.

The most important alias is gtaf, which is short for “grails test-app” for failed tests.

It will search through your test output directory and look for any tests that failed. If it finds any, it will rerun only those tests. Otherwise, it will rerun all tests. That makes it easy to just use gtaf all the time. If any tests fail, it will open them up using Console.app.

If you’re not on OSX, or would like to use something else to view the failed test logs, just modify the testlog alias to do something different.
Read the rest of this article »

7 Comments

Grails build-test-data presentation

2009/07/14

I gave a presentation tonight on the build-test-data grails plugin at the Groovy Users of Minnesota (GUM) meeting that was well received.

Lots of good questions from the people in attendance. Thanks to everyone for showing up.

Here’s a version of it on slideshow: Read the rest of this article »

6 Comments

Groovy closures make unit testing with “soft asserts” simple

2009/06/25

A recent blog post, Cedric Beust asks about how to cleanly implement “soft asserts”. Soft asserts are test assertions that don’t “fail fast”. Instead, all of the assertion failures in the test method are collected and reported at the end of the test.

So far, the proposals in the comments look fairly clunky to me and include defining whole sets of new methods like “assertEqualsButContinue(“foo”, “foo”)”, chaning assertions together jQuery-style, or using lists to hold all of our assertions.

Wouldn’t it be a lot nicer if we could continue to use the same methods that we’re already using?

In groovy, enabling soft assertions is easy with a little closure magic. Read the rest of this article »

8 Comments

Grails plugin build-test-data 0.2.1 released

2009/06/15

I’ve just released version 0.2.1 of the build-test-data grails plugin.

The build-test-data plugin makes creating integration test data easy. It decorates your domain objects with a “build” method that will create new domain instances and will automatically populate required fields with data and save it to the database. This enables you to create more maintainable tests where the data you create is targeted specifically at the situations you’re trying to test, without having to go through all of the ceremony of creating the rest of the object graph that you don’t care about.

// creates a new Book instance with all required fields 
// (like the Author that the book belongsTo) populated
def b = Book.build()

To learn more about the basics of the build-test-data plugin, see this blog post and check out the Basic Usage and Sample Code wiki pages.
Read the rest of this article »

1 Comment

Grails Testing Command Line Aliases

2009/06/14

I’ve recently thrown together a few different command line aliases that have been very helpful in my grails development and I thought others might benefit from them.

The aliases are primarily just the first letter of the words in the command, which makes them easy to remember (and saves on typing). Some examples:

gta                   # grails test-app
gtai                  # grails test-app -integration
gtaud AuthorService   # grails-debug-suspend test-app -unit AuthorService

Read the rest of this article »

5 Comments

Grails build-test-data Plugin Released!

2009/04/14

Creating maintainable test data is hard.

Often an entire object graph needs to be created to support the instantiation of a single domain object. This leads to either the cutting and pasting of that creation code, or relying on a canned set of objects that we’ve grown over time and maintained as the domain objects change. After a while, adding just one more Widget to that set of canned data ends up breaking tests just about every time.

There has to be a better solution, right? Read the rest of this article »

34 Comments