How can I have JUnit use a separate ClassLoader
for each test class it executes?
I am writing a JUnit TestRunner
for a library that sets a lot of static variables. I essentially want to reset all of these between each test class, without needing to know what all of them are. I do not want to be coupled to intimate knowledge of the framework, as whenever the library changes internally then my TestRunner
will break.
Before I go any further, I want to make absolutely clear that I really do want to do this.
Every other answer I can find on StackOverflow just says "don't do that," which isn't helpful. First person to answer with "static variables are dumb" wins a doughnut.
In the end I wrote my own, loosely based on another Stack Overflow answer (which didn't work for me).
It's now on GitHub, and Maven Central. https://github.com/BinaryTweed/quarantining-test-runner
<dependency>
<groupId>com.binarytweed</groupId>
<artifactId>quarantining-test-runner</artifactId>
<version>0.0.1</version>
</dependency>
To use it annotate your test classes accordingly:
@RunWith(QuarantiningRunner.class)
@Quarantine({"com.binarytweed"})
public class MyIsolatedTest {
...
The linked answer didn't work for me as the test class itself needs to be loaded in a separate ClassLoader
, as then all the classes it references will use the same loader. Quarantining is inclusive (rather than exclusive) as you need the JUnit @Test
annotations to be loaded by the parent ClassLoader
, otherwise JUnit can't find any testable methods as it uses Class<Test>
as a key in a lookup map.