Category Archives: groovy

Hamcrest matchers in Spock

Working with Spock we forget about a hidden gem – Hamcrest matchers. They are assertions turned into method objects. A matcher is usually parametrized with an expected value and is executed latel on the actual one.

When can we use it? For example in a table-driven specification with expected values in the table.

An expected value can be one of the following:

  • exact value
  • ‘not available’ text
  • any number

How can we express these assertions without Hamcrest?

then:
if (exactValue) {
    assert field == exactValue
} else if (notAvailable) {
    assert field == messageSource.getMessage('na', null, LocaleContextHolder.locale)
} else if (isNumber) {
    assert field.number
} else {
    assert false, 'Wrong test configuration'
}

where:
exactValue | notAvailable | isNumber
'12345'    | null         | null
null       | true         | null
null       | null         | true

Bufff…

  • there is a lot of boilerplate code
  • the specification is misleading – what does it mean that expected exactValue is null? Is it really null? Or simply this condition should not be checked?

How can we refactor this code using Hamcrest matchers?

then:
that field, verifiedBy

where:
verifiedBy << [
    org.hamcrest.CoreMatchers.equalTo('12345')
    notAvailable(),
    isNumber(),
]

...

def notAvailable() {
    org.hamcrest.CoreMatchers.equalTo messageSource.getMessage('na', null, LocaleContextHolder.locale)
}

def isNumber() {
    [
        matches: { actual -> actual.number },
        describeTo: { Description description -> 'should be a number' }
    ] as BaseMatcher
}

Result – shorter and more expressive feature method code.

You can find the full source code with mocked messageSource in this gist. For more information about Hamcrest matchers, check Luke Daley’s article.

Nesting categories in Groovy

Recently I discovered that Groovy categories can be nested. It means, you can inject a category into another one:

@Category(GroovyObject)
class FirstCategory {
    def method1() { }
}

@Category(GroovyObject)
@Mixin(FirstCategory)
class SecondCategory {
    def method2() {
        method1()
    }
}

@Mixin(SecondCategory)
class Mixee {
    def yetAnotherMethod() {
        method2()
    }
}

Before that ‘discovery’ I was injecting all categories into the final class. My code was not expressing the explicit dependency between the second and the first category:

@Mixin([FirstCategory SecondCategory)
class Mixee

Happy mixin’!

Smalltalk/Objective-C method calls in Groovy – @AsMessage AST transformation

I like method call (or message passing syntaxis) in Objective-C (inspired by Smalltalk). You can achieve more readable code that can be read like a natural language (taken from OCMock tests):

[mock stringByPaddingToLength:20 withString:@"foo" startingAtIndex:5];

In my current customer project we mock/stub some methods through metaclass or by using Grails mocks. (Spock up to 0.6 version is not able to mock neither dynamic nor static methods). To improve test code readability, I extract mock creation and configuration into a separate helper method:

def mockAddChargeOn(args, order) {
    order.metaClass.addChargeCalled = false
    order.metaClass.addCharge = { actualAmount, actualDueDate ->
        order.addChargeCalled = true
        assert actualAmount == args.expectsAmount
        assert actualDueDate == args.expectsDueDate
        args.returns
    }
}

so I can mock addCharge like this:

mockAddChargeOn order, expectsAmount: 1.0, expectsDueDate: tomorrow(), returns: aCharge

As you can see, I use named parameters extensively. Their drawback is lack of documentation through method signature. You have to read through the method body or rely on your IDE. IntelliJ IDEA is smart enough to figure out which named parameters a method supports and shows them in code completion. But not everybody uses this IDE.

I came up with a solution based on an AST transformation. If you annotate a method with @AsMessage, the transformation adds a new method with named parameters calling the original method:

@AsMessage
def mockAddChargeOn(order, expectsAmount, expectsDueDate, returns)

// Added by the AST transformation
def mockAddChargeOn(args, order) {
    mockAddChargeOn order, args.expectsAmount, args.expectsDueDate, args.returns
}

Your methods have clear signatures and you can call them using a more fluent syntax.

You find the source code and full documentation on GitHub:

https://github.com/mgryszko/message-transformation

If you are brave enough to test it out, spot a bug or want a new feature, use GitHub issues. Or you catch me on Twitter (@mgryszko).

Final note

I’m not going to apply this transformation on public API. My ‘target group’ is initially test code. The transformation should not substitute short method signatures with few parameters. Keep in mind than long signatures make method difficult to understand (Steve McConnell in Code Complete recommends using less than seven parameters; Robert C. Martin in Clean Code reduces this number to three).

Asynchronous tests with GPars (Osoco test gallery, part 4)

If you wrote multithreaded code in Groovy/Grails, I’m sure you stumbled upon the GPars library. It simplifies parallel processing – sometimes it’s as easy as wrapping a code fragment with a GPars closure, changing the iteration method (in our example from each to eachParallel) and passing the closure to a GPars pool. The library implementation handles the executor pool creation and adds new methods to collections.

Whenever I deliberately add multithreading, I always separate responsibilities (processing logic and concurrency handling). I wrap the single-threaded class with a new one, handing the parallel execution (creating a pool, managing threads, handling cancellation, etc.):

class MultithreadedProcessorService {
    ProcessorService processorService
    def threadPoolSize = ConfigurationHolder.config.threadPool.size

    void processMultithreaded(batches) {
        GParsPool.withPool(threadPoolSize) {
            batches.eachParallel { batch ->
                processorService.process(batch)
            }
        }
    }
}

class ProcessorService {
    void process(batch) {
        // some processing
    }
}

To test the multithreaded class you can you use Spock interactions. As opposed to Groovy and Grails mocks, they are thread-safe and you won’t get any weird and unstable results:

class MultithreadedProcessorServiceSpec extends UnitSpec {
    private MultithreadedProcessorService multithreadedProcessorService
    // Using Spock mocks because they are thread-safe
    private ProcessorService processorService = Mock(ProcessorService)

    def setup() {
        mockConfig('threadPool.size=2')
        multithreadedProcessorService = new MultithreadedProcessorService(
            processorService: processorService
        )
    }

    def 'processes batches using multiple threads'() {
        given:
        def batches = [[0, 1], [2, 3, 4], [5]]
        def processedBatches = markedAsNotProcessed(batches)

        when:
        multithreadedProcessorService.processMultithreaded(batches)

        then:
        batches.size() * processorService.process({ batch ->
            processedBatches[batch] = true
            batch in batches
        })
        assertAllProcessed(processedBatches)

    }

    private markedAsNotProcessed(batches) {
        batches.inject([:]) { processed, batch ->
            processed[batch] = false
            processed
        }
    }

    private void assertAllProcessed(batches) {
        assert batches*.value == [true] * batches.size()
    }
}

This post series present the best of Osoco tests – tests that were tricky or we are just proud of. You can find a runnable source code for this test and more in the Grails Test Gallery project shared on GitHub.

Grails base persistence specification (Osoco test gallery, part 3)

In our projects we include at least one integration test per domain class. We want to assure us that the GORM mapping is correct and the class is persistable in the target database.

The test plan is simple:

  • create a valid persistable sample of the domain object
  • save it
  • clear Hibernate first level cache (i.e. flush and clear current session)
  • retrieve the object once again and compare it with the previously saved object. They must be equal as by equals() but be different object references

We put the steps above in a base abstract specification. In concrete specifications we implement merely the factory method spawning a persistable object instance.

abstract class PersistenceSpec extends IntegrationSpec {
    SessionFactory sessionFactory

    protected abstract createPersistableDomainObject()
    
    def 'persistable domain object should be able to be saved and retrieved'() {
        given:
        def persistableDomainObject = createPersistableDomainObject()

        when:
        def savedDomainObject = persistableDomainObject.save()

        then:
        savedDomainObject.id != null

        when:
        clearFirstLevelCache()

        def retrievedDomainObject = persistableDomainObject.class.get(savedDomainObject.id)

        then:
        savedDomainObject == retrievedDomainObject
        !savedDomainObject.is(retrievedDomainObject)
    }

    private clearFirstLevelCache() {
        sessionFactory.currentSession.flush()
        sessionFactory.currentSession.clear()
    }
}

This post series present the best of Osoco tests – tests that were tricky or we are just proud of. You can find a runnable source code for this test and more in the Grails Test Gallery project shared on GitHub.

Follow

Get every new post delivered to your Inbox.

Join 318 other followers