Usage
Provides an easy way to initialize a singleton exactly once:
public class Singleton { public static Singleton instance() { return Globals.getOrSetTo(Singleton.class, Singleton::new); } protected Singleton() {} ... }
In a testing environment, you can wipe the globals to get a clean state or to replace the standard implementation with a testing one.
public class SingletonTest { static class SingletonDev extends Singleton { ... } @Test public void someTest() { try (AutoCloseable wipeGlobals = GlobalsDev.wipe()) { SingletonDev dev = new SingletonDev(); GlobalsDev.install(Singleton.class, dev); ... } } }
The "trick" is that GlobalsDev is shipped in a different artifact than the rest, so you can be sure that your Globals can only be changed in tests, and never in production code:
dependencies { implementation 'com.diffplug.durian-globals:durian-globals:1.0.0' testImplementation 'com.diffplug.durian-globals:durian-globals.dev:1.0.0' }
Built-ins
There are some globals that people frequently want control over during testing.
Time
You can use public static long Time.now() as a replacement for System.currentTimeMillis(). And in a test, you can replace it with TimeDev.
@Test public void someTimeDependentTest() { try (AutoCloseable wipeGlobals = GlobalsDev.wipe()) { TimeDev time = TimeDev.install(); time.setUTC(LocalDate.parse("2019-03-30")); ... // exercise code that uses `Time.now()` } }
Requirements
DurianGlobals requires nothing but Java 8+.
In the wild
- Integration testing the spotless-changelog gradle plugin
