Use Cases for JUnit Rules
Sometime ago I blogged about JUnit @Rule Annotation. In the meantime I got the chance to use rules in a real project. I must say: Rules rock! Let me tell you about my use cases.
- I am working on a Swing project (It’s OK, it’s not as bad as it sounds). We have many tests that create components and check certain properties. Although they never get shown in the traditional sense, Swing documentation requires all manipulation of Swing Components to happen in the Event Dispatch Thread. We have an EDTRule, which runs every test using SwingUtilities.invokeAndWait(). It works like a charm. We actually had a dozen tests that would fail under real weird conditions, which behave nicely since they where adorned with an EDTRule. While the Rule takes care on the threading requirements, test stay nicely clean and don’t get poluted by SwingUtilities and Runnable implementations.
- Another class of tests runs scripts against a database. In order to reproduce what the database admins will do, we use SQL/Plus for this (If you don’t know SQL/Plus consider yourself lucky). One problem with these test is, that a small bug in a script might cause SQL/Plus to await user input. In order to prevent the test to hang forever we implemented a TimeoutRule. Each script that gets started puts its Process instance into the rule instance, and the rule instance will destroy the Process after some specified time. Note: JUnit comes with a similar Timeout rule, which will let the test fail after a timeout.
- We have an ApplicationRegistry, which is basically a singleton map containing Implementations for Interfaces. Each test should setup the ApplicationRegistry with whatever is needed, and clean it up afterwards. Often developers forget the last part (When I say developers I am talking about myself). For this we have an ApplicationRegistryRule. It cleans the ApplicationRegistry before the test and after the test. Since it is only one Rule instead of a Before and an After method, it is easier not to forget one half of it. But the Rule does more: Before cleaning it, it checks if the ApplicationRegistry is empty. If it isn’t this means, some other test left it dirty. In this case the Rule calls Assertion.fail(). This way we found (probably) every test which left the ApplicationRegistry dirty. Very cool. A similar approach should work for other central resources like Spring Contexts and the like.






It’s not clear to me what rules can achieve that you can’t do with @Before/@After and @BeforeClass/@AfterClass, can you expand?
- You can determine / manipulate / set the thread in which the test executes
- you can skip tests or run them multiple times
- Since you have access to the signature of the test, you can make the action you perform dependent of the test (especially annotations are useful, but the name of the test might be of use as well, e.g. for gathering statistics).
- With rules before + after are kind of bundled in one package, so you can’t forget about the after.
- Rules are easier to reuse, and more compact when used. They are a little more verbose on declaration.
Hi,
when I read this yesterday, I wasn’t sure if these Rules are a big feature. My fear was, that Rules could lead to confusion, ’cause they could be hidden very deeply (just like aspects).
But today I think differently. I am using Rules to “annotate” messages for failed assertions. Now the test developer just has to annotate his test method with a simple annotation, and all error messages for the test are decorated with informations about the corresponding test case in our test management software (HPQC).
Thank you very much for your investigations, Jens, and greetings to the whole LINEAS crew (though mostly unknown these days).
sorry Jens für die Einmischung in einen technischen Blog aber bist Du der Jens Schauder der seine Kindheit in Lemwerder verbracht hat, Bruder von Andrea Schauder? falls ja würde ich mich über eine Mail freuen, ansonsten vergesse es einfach
danke und schönen Tag noch…