DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Languages
  4. Only a Masochist Would Write Unit Tests in Java. Be Smarter, Use Groovy (or Scala…).

Only a Masochist Would Write Unit Tests in Java. Be Smarter, Use Groovy (or Scala…).

Jakub Holý user avatar by
Jakub Holý
·
Oct. 21, 11 · Interview
Like (0)
Save
Tweet
Share
9.70K Views

Join the DZone community and get the full member experience.

Join For Free

I like writing unit tests but Java doesn’t make it particularly easy. Especially if you need to create objects and object trees, transform objects for checking them etc. I miss a lot a conscise, powerful syntax, literals for regular expressions and collections, conscise, clojure-based methods for filtering and transforming collections, asserts providing more visibility into why they failed. But hey, who said I have to write tests in the same language as the production code?! I can use Groovy – with its syntax being ~ 100% Java + like thousand % more, optional usage of static/dynamic typing, closures, hundreds of utility methods added to the standard JDK classes and so on. Groovy support for example in IntelliJ IDEA (autocompletion, refactoring …) is very good so by using it you loose nothing and gain incredibly much. So I’ve decided that from now on I’ll only use Groovy for unit tests. And so far my experience with it was overwhelmingly positive (though few things are little more complicated by the positives more than compensate for them). Read on to find out why you should try it too.

(The arguments here focus on Groovy but I guess similar things could be said about JRuby, Scala etc. – with the exception of Java code compatibility, which you only get in Groovy.)

Few examples

Some of the example below use some Groovy magic but don’t be scared. You can write Groovy just as if it was Java and only learn and introduce its magic step by step as you need it.

Bean construction:

def testBean = new Customer(fname: "Bob", sname: "Newt", age: 42)
// Java: c = new Customer(); c.setFname("Bob"); c.setSname("Newt"); c.setAge(42);

Reading a file:

assert test.method() == new File("expected.txt").getText()
// == actually calls equals

Checking the content of a collection/map:

assert customerFinder.findAll().collect {it.sname}.sort() == ["Lizard","Newt"]
// Java: too long to show here (extract only surnames, sort them, compare ...)
assert getCapitalsMap() == ["UK" : "London", "CR" : "Prague"]

Regular expressions:

assert ("dog1-and-dog2" =~ /dog\d/).getAt([0,1]) == ["dog1", "dog2"]

What is Groovy?

Groovy 1.8 is a mature scripting language for the JVM written as an extension of Java with optional dynamic typing, closures, and more. It’s now developed by SpringSource, the company behind the Spring framework.

As mentioned, nearly all Java code is a valid Groovy code with basically one exception: To initialize an array you can’t use { … } (for that would be a closure), you must use [...] instead (notice that by default it actually creates a List, only when assigned to an array variable or casted to array will it produce an array). Make sure to check the few common gotchas before you dive into using Groovy.

You can experiment with Groovy online in the GAE Groovy console.

Groovy features especially beneficial for testing

General

  • Dynamic typing at request => conscise, avoids code cluttered with casts

Collections: Closure-based methods like every, each, find

Files: Read all the text with one call, withReader { .. } etc.

Testing/advanced:

  • assert- you can use the Java keyword assert instead of JUnit methods, upon failure Groovy will provide you with pretty good info of what went wrong:
    Assertion failed: 
    
    assert config.getResolvers()) == ["h:dataTable" : resolver, "my:dt2" : null]
           |      |                |                  |
           |      |              false                |
           |      |                                   MyResolver@731d2572
           |      [h:dataTable:MyResolver@731d2572, my:dt2:MyResolver@731d2572]
           LocalVariableConfiguration@7e859a68
  • Here-docs: embed multi-line strings easily in a test (also supports replacing references like $variable with values)
  • Implementing interfaces with a map (map coercion)
  • Use expandos to define dynamic beans (similarly to JavaScript, you instantiate an Expando and just add properties and closures as methods) – as described on the linked page, expandos and maps are usually enough to replace a mocking library
  • Build-in mocking
  • With Groovy you can of course also use Spock, the excellent specification & testing framework

Complications

  • Neither JUnitMax nor Infinitest (in IntelliJ) seem to support Groovy test cases
  • You need a decent IDE such as IntelliJ IDEA
  • If using Maven, you have to explicitely configure the GMaven plugin (esp. with a newer Groovy version)
  • IntelliJ 10.5: Click & alt+enter on a non-existing method to create it only works if the target type is a nested class within the test, not if it is a standalone Java class (so I just create my class there and when done TDDing I extract it into a top-level Java class)

Conclusion

Groovy makes test writing much more productive and thus developers happy. I intend to use on all my open source projects and to try push it into our commercial projects too. You should give it a try too!

Additional Links

  • DefaultGroovyMethods.java (src): defines the methods added to all objects
  • DefaultTypeTransformation.java: methods used internally to convert between types and when using “as aType” – useful to know what as can convert

 

From http://theholyjava.wordpress.com/2011/10/18/only-a-masochist-would-write-unit-tests-in-java-be-smarter-use-groovy-or-jruby-or-st-else-similar/

Groovy (programming language) unit test Java (programming language) intellij

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Custom Validators in Quarkus
  • Building Microservice in Golang
  • How To Build a Spring Boot GraalVM Image
  • Comparing Map.of() and New HashMap() in Java

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: