Peter Ledbrook wrote an interesting post Exploring Kotlin about his initial experiences with Kotlin. Since I’ve been getting quite into Kotlin recently I thought I’d follow that up with some of my own observations as well as responding to some of the questions he raised.
Yesterday I posted about an implementation of a simple remote service polling mechanism using RxJava. One of the things I particularly liked when applying this pattern at work was how straightforward it was to unit test.
Often when dealing with asynchronous processing unit testing can be pretty painful. Typically you need to use a mechanism such as Java’s
CountDownLatch or Spock’s
PollingConditions to synchronize threads before making assertions. Allowing processing to run asynchronously, especially when testing scheduled activity can make tests very slow as well.
Ideally tests the asynchronous nature of the code is abstracted and the timer can be faked out. This is exactly the approach that RxJava takes.
I’ve done odd bits of playing around with RxJava before but never dived into it very deeply. Today I wanted to re-implement an unreliable background polling operation and Tomás Lin suggested I look at using RxJava. This may be an obvious implementation to some but I had to do a bit of experimentation (and searching Stack Overflow) to come up with it.
Imagine we’re polling a web-service regularly. The service returns a JSON array of independent items (think events since last poll, Tweets with a particular hashtag or something similar). We want to do some processing (filtering, parsing to a type) on each item and then pass them off to a handler.
For years I’ve used the Joda Time library to provide a nicer alternative to the horrible mutable
java.util.Date class and the terrifying abyss of
java.util.Calendar. One thing, as a fanatical tester, that really appealed to me was the existence of the
DateTimeUtils class. All the Joda Time types use
DateTimeUtils as a source of the current instant and it exposes methods that allow tests to fix or offset the value that’s returned. That can rule out some irritating flakiness in tests and enable testing of time zone / daylight savings bugs, timeout logic and so on while retaining the encapsulation of timestamp generation in production code.
Of course, when you look at
DateTimeUtils with purist eyes it’s a horrible hack. A static singleton encapsulating global mutable state! I guess that was the attitude of those responsible for JSR-352 that created the new
java.time package which is largely based on Joda Time. One of the things that wasn’t carried over from Joda Time is the
DateTimeUtils class. Instead factory methods such as
Instant.now() use a
Clock object – by default
One objection to the practice of TDD I’ve heard from several different people is along the lines of “I don’t know exactly what I’m building at the outset, the code is experimental, so how can I write tests for it?”
Frequently it is the case that you have an idea but don’t know the mechanics of how you’re going to implement it. I find this particularly when I’m writing code that extends a third-party library. You don’t know exactly where the API hooks you’ll need to use are, your understanding of the API is fuzzy and you expect to learn it as you go. So how do you test-drive in that situation?
Mock factory method (as well as factories for the other types of test double;
Spy) accepts a single interface representing the type you need a test double for. But what should you do if you need a test double that implements multiple interfaces?
Groovy’s power assert and Hamcrest matchers both solve a similar problem – getting decent diagnostic information from an assertion failure. When writing JUnit or Spock tests in Groovy it’s typical to not use Hamcrest matchers as the power assert is so much simpler and just as effective. It’s worth bearing in mind, though that Hamcrest is also for helping clearly express the intent of an assertion. Spock provides support for Hamcrest matchers and I recently ran into a situation where I think it was the right thing to use.
I find Groovy Closures can sometimes behave in ways that, once I think about it, make perfect sense but initially seem surprising. One example of this is the fact that closures declared in a parent class cannot “see” private fields of that class when run in the context of a child class.
I’m a big fan of Groovy’s
@CompileStatic feature – so much so that I’ve updated the Groovy class template in IntelliJ IDEA to use it by default. I should stress I don’t do this because I believe non-statically compiled Groovy to be slow – it isn’t.
Recently Peter Ledbrook reminded me of one drawback which is that method dispatch is statically bound when using
@CompileStatic like it is in Java. This means that the behavior of calling polymorphic methods can change when argument types are not known at compile time.
I posted previously about configuring a Gradle project to ensure that only the indy version of Groovy (that is the variant that supports Java 7’s invokedynamic bytecode instruction) is included in the dependency graph. However, just including that version of the Groovy jar is not enough to make your Groovy code compile in such a way that it uses invokedynamic.