Groovy MetaClass Magic in Unit Tests

As you may or may not know, Groovy has the concept of MetaClasses. MetaClasses enable you to add or change methods at runtime. This is especially handy when doing some mocking during a unit test (or, in our case, GrailsUnitTestCases). By mocking methods, you can mock out certain dependencies or behavior which you might not want during a unit test. An example:

In this case, if you want to test the logic of the PersonAdapter without using the complex operations in the service, on way to test this by using some MetaClass magic, as can be seen below:

While this might be not be the optimal example or test (you might consider using Mocks instead), there’s a flaw in this test. Since the complexOperation is now metaClassed on the class level, instead of on the object, it means that future tests will also be affected, including Integration tests. This might lead to some very unexpected behaviors, which are sometimes hard to track down.

There are two ways to ‘fix’ this:

  1. Always call the super.tearDown() in tests. This will reset the Groovy meta registry to it’s normal state. However, you need to explicitly call ‘registerMetaClass’ in tests to allow Grails to clean this up. If you forget this, you’re metaClass change can affect other tests too. To prevent that, we have option 2.
  2. Use the MetaClassMixin.

The MetaClassMixin is a simple class we use in our project to automatically register metaClasses in the GroovySystem’s MetaClassRegistery. Since we are using only the MetaClassMixin to do metaclass magic instead of doing it directly on classes, we can never forget to register the class anymore. This has saved us in many cases. An example usage can be seen below:

Using the MetaClassMixin, you no long have to worry about registering your MetaClassed classes, or, more importantly forgetting to register them! Below, you can find the source of the MetaClassMixin (this mixin has been written by Levi Hoogenberg, so credits for that!). Feedback on this welcome of course!

Happy metaClassing!

Testing reusable validation

In the application we are developing, a lot of input validation takes place. Most of the input is validated using Command Objects, which are a breeze to use thanks to Grails’ fantastic way of integrating them. However, in some of our Command Objects, there’s some overlap, most notably in the validation part. For example, we use a CreateCustomerCommand and a OrderProductCommand, which both have a ‘zipcode’ field, which, in our case, matches the regular expression [0-9]{4}[a-zA-Z]{2}. Since we don’t want to duplicate this regular expression, we need to come up with a solution to be able to reuse this. Read more