This is my first every “quicky”.
Recently I didn’t have time to write posts as I was travelling back and forth to conferences, code katas and so on. I have a long list of things to write about, and not enough time to give it attention they need. In the meantime I get distracted by my “pet” projects, articles and posts. Usual thing. Ok, enough excuses 🙂
Whenever I got a chance to squeeze time and space, I am working in a spare time on my projects… , actually haven’t committed to my “pet” projects a single line of code for a month or so. This is sad story about every single of my “pet” projects. It is not that I am lazy :), it is more because of a broken connection in my brain. Because of this broken connection when I build concept or an idea for a “pet” project my brain “gets high” pretty fast, I work on it day and night, commits flow into repository like waters of holy river Ganges, until the “aha” moment.
Aha, I know how to implement it.
Aha, I am able to validate and justify the concept and design in my head.
Aha, I proved that it can be done.
Broken connection in my brain causes short-circuit between my synapses, which then sends “it is boring” message to the center of “pleasure department” 🙂
Somebody can say, what a waste of time and energy. Actually it is not. With every of my “pet” projects I have learned something, about programming languages, testing and frameworks. As “pet” project doesn’t give any value to the community I started to think that it would be at least worth to share what I have learned.
So this is idea of “quickies”. Short posts, about a small little things I have learned. Some of them will be obvious, some of them will give you “aha” moment.
In my most recent project I have lots of fun with threads, concurrency and testing. I am again amazed how asynchronous communication and concurrency can hurt your brain during testing. Sometimes I want to give up, and narrow boundaries of testable parts of the system. It is tempting, so tempting. But one the other side, it is much more tempting to solve this problem.
In one of cases, I want to test if message send asynchronously is being delivered with proper message content. I know that this can be quite easily done with a little bit of coding here and there.But when I looked at my code after few days I didn’t understand what was going on in it. I needed something which expresses my intent in a more descriptive way, and I found it. It is called SettableFuture
, from Google Guava library.
Here is short snippet how it works.
import com.google.common.util.concurrent.SettableFuture; final SettableFuture<String> future = SettableFuture.<String> create(); new Thread(new Runnable(){ public void run(){ future.set("Hello world!!!"); } }).start(); String result = future.get(4, TimeUnit.SECONDS); assertThat(result).isNotEmpty();
How it works?
SettableFuture
implements java.util.concurrent.Future
interface, which in short represents result of asynchronous operation. Aha 🙂
According to contract of method Future.get(long timeout,TimeUnit unit)
it will block until you get result of operation, or throw java.util.concurrent.TimeoutException
when operation timeout occurs.
What SettableFuture
gives you? SettableFuture
is the implementation of java.util.concurrent.Future
, which gives you ability to set operation result. Nothing more, nothing less. Thanks to this you can pass SettableFuture
to asynchronous operation and notify test code whenever results are available.
Because it implements java.util.concurrent.Future
contract your tests will not run forever and in case of time out you can test timeout with expected exceptions. Of course if asynchronous call executes faster then you reach future.get(4,TimeUnit.SECONDS)
it will return immediately returning results of asynchronous operation.
That’s all for today, in my first “quicky” :). I hope you liked it.
I like this quicky format!
For testing I’d use an anonymous mock implementation of Future which returns the desired value (i.e. “Hello world!!!”)
Yeah, you can mock it too, but SettableFuture works when you want to assert value returned by async operation, and somehow you need to get access to this value, the other thing is that it allows you to assert things like timeouts, but definitively there are cases where I would use mock :), thanks