This post was originally published on the Transylvania JUG blog.
Testing multi-threaded code is hard. The main problem is that you invoke your assertions either too soon (and they fail for no good reason) or too late (in which case the test runs for a long time, frustrating you). A possible solution is to declare an interface like the following:interface ActivityWatcher {
void before();
void after();
void await(long time, TimeUnit timeUnit) throws InterruptedException, TimeoutException;
}
It is intended to be used as follows:
- “before” is called before the asynchronous task is delegated to an execution mechanism (threadpool, fork-join framework, etc) and it increments an internal counter.
- “after is called after the asynchronous task has completed and it decrements the counter.
- “await” waits for the counter to become zero
- There should be a single ActivityWatcher per test (injected trough constructors or a dependency injection framework)
- In production code you will use a dummy/noop implementation which removes any overhead.
- This only works for situations where the asynchronous are kicked of immediately. Ie. it doesn’t work for situations where we have periodically executing tasks (like every 5 seconds) and we would want to wait for the 7th tasks to be executed for example.
- use the default UncaughtExceptionHandler to capture all exceptions and rethrow them in the testrunner if they arrise (not so nice because it introduces global state – you can’t have two such tests running in parallel for example)
- Extend activity watcher and code calling activity watcher such that it has a “
collect(Throwable)
” method which gets called with the uncaught exceptions and “await
” rethrows them.
0 comments:
Post a Comment
You can use some HTML tags, such as <b>, <i>, <a>. Comments are moderated, so there will be a delay until the comment appears. However if you comment, I follow.