Singleton and unit testing - java

The Effective Java has the following statement on unit testing singletons
Making a class a singleton can make it difficult to test its clients, as it’s impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type.
Can anyone explain the why this is so ?

You could use reflection to reset your singleton object to prevent tests from affecting each other.
#Before
public void resetSingleton() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field instance = MySingleton.class.getDeclaredField("instance");
instance.setAccessible(true);
instance.set(null, null);
}
Ref: unit-testing-singletons

The problem isn't testing singletons themselves; the book is saying that if a class you are trying to test depends on a singleton, then you will likely have problems.
Unless, that is, you (1) make the singleton implement an interface, and (2) inject the singleton to your class using that interface.
For example, singletons are typically instantiated directly like this:
public class MyClass
{
private MySingleton __s = MySingleton.getInstance() ;
...
}
MyClass may now be very difficult to automatedly test. For example, as #Boris Pavlović notes in his answer, if the singleton's behaviour is based on the system time, your tests are now also dependent on the system time, and you may not be able to test cases that, say, depend on the day of the week.
However, if your singleton "implements an interface that serves as its type" then you can still use a singleton implementation of that interface, so long as you pass it in:
public class SomeSingleton
implements SomeInterface
{
...
}
public class MyClass
{
private SomeInterface __s ;
public MyClass( SomeInterface s )
{
__s = s ;
}
...
}
...
MyClass m = new MyClass( SomeSingleton.getInstance() ) ;
From the perspective of testing MyClass you now don't care if SomeSingleton is singleton or not: you can also pass in any other implementation you want, including the singleton implementation, but most likely you'll use a mock of some sort which you control from your tests.
BTW, this is NOT the way to do it:
public class MyClass
{
private SomeInterface __s = SomeSingleton.getInstance() ;
public MyClass()
{
}
...
}
That still works out the same at run-time, but for testing you are now again dependent on SomeSingleton.

Mocks require interfaces, because what you're doing is replacing the real underlying behavior with an imposter that mimics what you need for the test. Since the client only deals with an interface reference type, it doesn't need to know what the implementation is.
You can't mock a concrete class without an interface, because you can't replace the behavior without the test client knowing about it. It's a completely new class in that case.
It's true for all classes, Singleton or not.

I think it actually depends on the implementation of the singleton access pattern.
For example
MySingleton.getInstance()
Might be very dificult to test while
MySingletonFactory mySingletonFactory = ...
mySingletonFactory.getInstance() //this returns a MySingleton instance or even a subclass
Doesn't provide any information about the fact that its using a singleton. So you can freely replace your factory.
NOTE: a singleton is defined by being only one instance of that class in an application, however the way it's obtained or stored doesn't have to be through static means.

It's oh so simple.
In unit-testing, you want to isolate your SUT (the class you're testing).
You don't want to test a bunch of classes, because that would defeat the purpose of unit-testing.
But not all classes do everything on their own, right? Most classes use other classes to do their work, and they kind of mediate between other classes, and add a bit of their own, to get the final result.
The point is - you don't care about how the classes your SUT depends on work. You care how your SUT works with those classes. That's why you stub or mock the classes your SUT needs. And you can use those mocks because you can pass them in as constructor parameters for your SUT.
With singletons - the bad thing is that the getInstance() method is globally accessible. That means that you usually call it from within a class, instead of depending on an interface you can later mock. That's why it's impossible to replace it when you want to test your SUT.
The solution is not to use the sneaky public static MySingleton getInstance() method, but to depend on an interface your class needs to work with. Do that, and you can pass in test doubles whenever you need to.

Singleton objects are created without any control from the outside. In one of the other chapters of the same book Bloch suggests using enums as default Singleton implementation. Let's see an example
public enum Day {
MON(2), TUE(3), WED(4), THU(5), FRI(6), SAT(7), SUN(1);
private final int index;
private Day(int index) {
this.index = index;
}
public boolean isToday() {
return index == new GregorianCalendar().get(Calendar.DAY_OF_WEEK);
}
}
Let's say we have a code that should be executed only on weekends:
public void leisure() {
if (Day.SAT.isToday() || Day.SUN.isToday()) {
haveSomeFun();
return;
}
doSomeWork();
}
Testing leisure method is going to be pretty hard. Its execution is going to be dependent on the day when it is executed. If it executes on a weekday doSomeWork() will be invoked and on weekends haveSomeFun().
For this case we would need to use some heavy tools like PowerMock to intercept the GregorianCalendar constructor, return a mock which will return an index corresponding to a weekday or weekend in two test cases testing both execution paths of the leisure method.

it’s impossible to substitute a mock implementation for a singleton
This is not true. You can subclass your singleton and setter inject a mock. Alternatively, you can use PowerMock to mock static methods. However the need to mock singletons can be symptomatic of poor design.
The real problem is Singletons when abused turn into dependency magnets. Since they are accessible everywhere, it can appear more convenient to put the functions you need in them rather than delegating to an appropriate class, especially for programmers new to OOP.
The testability problem is now you have a bunch of Singletons that are accessed by your object under test. Even though the object probably only uses a small fraction of methods in the Singletons, you still need to mock each Singleton and figure out which methods are depended on. Singletons with a static state (Monostate pattern) are even worse because you can have to figure out which interactions between objects are affected by the Singleton's state.
Used carefully, Singletons and testability can occur together. For instance, in absence of a DI framework, you can use Singletons as your Factories and ServiceLocators, which you can setter inject to create a fake service layer for your end-to-end tests.

It is possible, see the example
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class DriverSnapshotHandlerTest {
private static final String MOCKED_URL = "MockedURL";
private FormatterService formatter;
#SuppressWarnings("javadoc")
#Before
public void setUp() {
formatter = mock(FormatterService.class);
setMock(formatter);
when(formatter.formatTachoIcon()).thenReturn(MOCKED_URL);
}
/**
* Remove the mocked instance from the class. It is important, because other tests will be confused with the mocked instance.
* #throws Exception if the instance could not be accessible
*/
#After
public void resetSingleton() throws Exception {
Field instance = FormatterService.class.getDeclaredField("instance");
instance.setAccessible(true);
instance.set(null, null);
}
/**
* Set a mock to the {#link FormatterService} instance
* Throws {#link RuntimeException} in case if reflection failed, see a {#link Field#set(Object, Object)} method description.
* #param mock the mock to be inserted to a class
*/
private void setMock(FormatterService mock) {
Field instance;
try {
instance = FormatterService.class.getDeclaredField("instance");
instance.setAccessible(true);
instance.set(instance, mock);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Test method for {#link com.example.DriverSnapshotHandler#getImageURL()}.
*/
#Test
public void testFormatterServiceIsCalled() {
DriverSnapshotHandler handler = new DriverSnapshotHandler();
String url = handler.getImageURL();
verify(formatter, atLeastOnce()).formatTachoIcon();
assertEquals(MOCKED_URL, url);
}
}

Use PowerMock to mock Singleton class (SingletonClassHelper) instance and non-static method (nonStaticMethod) which is called in task.execute().
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#PrepareForTest({ SingletonClassHelper.class })
#RunWith(PowerMockRunner.class)
public class ClassToTest {
#InjectMocks
Task task;
private static final String TEST_PAYLOAD = "data";
private SingletonClassHelper singletonClassHelper;
#Before
public void setUp() {
PowerMockito.mockStatic(SingletonClassHelper.class);
singletonClassHelper = Mockito.mock(SingletonClassHelper.class);
when(SingletonClassHelper.getInstance()).thenReturn(singletonClassHelper);
}
#Test
public void test() {
when(singletonClassHelper.nonStaticMethod(parameterA, parameterB, ...)).thenReturn(TEST_PAYLOAD);
task.execute();
}
}

durian-globals does lazy double-locked initialization of singletons, but also has a simple test-only API which allows you to replace the implementation for unit testing.

As far as I know, a class implementing a Singleton cannot be extended (superclass constructor is always called implicitly and the constructor in a Singleton is private). If you want to mock a class you have to extend the class. As you see in this case it wouldn't be possible.

The problem with singletons (and also with static methods) is that it makes it hard to replace the actual code with a mocked implementation.
For example consider the following code
public class TestMe() {
public String foo(String data) {
boolean isFeatureFlag = MySingletonConfig.getInstance().getFeatureFlag();
if (isFeatureFlag)
// do somethine with data
else
// do something else with the data
return result;
}
}
It is not easy to write a unit test for the foo method and verifying the correct behavior is performed.
This is because you can't easily change the return value of getFeatureFlag.
The same problem exists for static methods - it's not easy to replace the actual target class method with a mock behavior.
Sure, there are workarounds like powermock, or dependency injection to the method, or reflection in tests.
But it is much better not to use singletons in the first place

Below there is the solution I had to adopt with some immutable Kotlin singleton to test them
Suppose you have a singleton class like this:
class MySingleton private constructor(
{your dependencies}
) {
companion object {
#JvmStatic
private var INSTANCE: MySingleton? = null
#JvmStatic
fun getInstance(): MySingleton {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: MySingleton(
{your dependencies}
).also {
INSTANCE = it
}
}
}
}
}
You can do this in your kotlin junit tests:
#After
fun after() {
val instance = MySingleton.Companion::class.memberProperties.find {
it.name == "INSTANCE"
}
instance!!.isAccessible = true
instance.javaField!!.set(null, null)
}
You just need to add the kotlin-reflect artifact to your dependencies

Related

Java - How to test the non-abstract methods of an abstract class?

I have an abstract class that features no abstract methods... How would one go about testing this? Can I simply import it into a test class and go about business as usual?
Example:
public abstract class SomeAbstractClass implements SomeOtherClass {
// Some variables defined here
private static final String dbUrl = System.getProperty("db.url");
// Some public methods
public String doSomethingToUrl(String url) {
url = url + "/takeMeSomewhereNice";
}
}
Say I pass in an arg for db.url of localhost:8080, and I wanted to test that the doSomethingToUrl method did output the new string... Would it still be in this format?
public class TestUrl {
SomeAbstractClass sac = new SomeAbstractClass();
#Test
public void testUrlChange() throws Exception {
String testUrl = "localhost:8080";
assertThat("localhost:8080/takeMeSomewhereNice",
sac.doSomethingToUrl(testUrl));
}
}
You wouldn't be able to create an instance of just SomeAbstractClass, no - but you could create an anonymous subclass:
private SomeAbstractClass sac = new SomeAbstractClass() {};
You may well want to create a concrete subclass just for the sake of testing though - so that any time you do add abstract methods, you just need to put them there.
While I suspect you could use a mocking framework for this, I suspect it would add more complexity for little benefit, unless you need to check under what situations the abstract methods are called. (Mocks are great for interaction testing, but can be brittle for other purposes.) It could easily make for more confusing error messages (due to the infrastructure involved) as well.
You cannot initialize an abstract class, so your test class wouldn't compile as is.
You can either use an anonymous instance (the example below should suffice):
SomeAbstractClass sac = new SomeAbstractClass(){};
However, I would actually recommend you mock the class by means of a mocking framework such as Mockito or EasyMock.

How to mock an object created via Class.newInstance(className)?

I'm trying to add unit tests to some legacy code that has a String class name passed to it and that creates an object implementing a particular handler interface using Class.newInstance(String className). I can control the class name I'm passing, I can get a pointer to the new handler object (via a getHandler() call), and I would like to observe calls to it using Mockito.
My current solution is:
Create a new test class TestHandler that implements the interface.
Have that test class contain a Mockito mock object that also implements the interface.
Manually pass through all the interface methods to the mock object.
Make the mock object accessible via a getMock() method.
Observe the object by making verify() calls to objectUnderTest.getHandler().getMock().
This works, but feels a little inelegant, especially having to manually write all the pass-thru methods.
Is there a better solution?
Fundamentally, you're running into the same problems as trying to test a newly-created instance using new; the Class.newInstance (probably properly Class.forName(foo).newInstance()) doesn't hurt you, but doesn't help you either.
As a side note, your TestHandler sounds like a general purpose delegate implementation, which sounds pretty useful anyway (particularly if you ever need to write a Handler wrapper). If it is, you might want to promote it to be adjacent to your Handler in your production code tree.
Though I recognize that you mention legacy code, this becomes very easy if you are allowed to refactor to include a testing seam. (Ignoring reflective exceptions here for ease of explanation.)
public ReturnType yourMethodUnderTest(String className) {
return yourMethodUnderTest(Class.newInstance(className));
}
/** Package private for testing. */
public ReturnType yourMethodUnderTest(Handler handler) {
return yourMethodUnderTest(Class.newInstance(className));
}
You could also extract the object creation and replace it in your test:
/** Instance field, package-private to replace in tests. */
Function<String, Handler> instanceCreator =
( x -> (Handler) Class.forName(x).newInstance());
public ReturnType yourMethodUnderTest(String className) {
Handler handler = instanceCreator.apply(className);
// ...
}
You could even just extract it to a method and replace it in your test:
public ReturnType yourMethodUnderTest(String className) {
Handler handler = createHandler(className);
// ...
}
/** Package private for testing. */
Handler createHandler(String className) {
return Class.forName(className).newInstance();
}
#Test public void yourTest() {
// Manually replace createHandler. You could also use a Mockito spy here.
ObjectUnderTest objectUnderTest = new ObjectUnderTest() {
#Override Handler createHandler(String className) {
return mock(Handler.class);
}
}
// ...
}
Side note: Even though Mockito creates a named dynamic type, you almost certainly will not be able to hack it in and allow your code to create it by name. This is because the call to mock registers the instance within Mockito's internal state.
// BAD: Unlikely to work
#Test public void yourTest() {
objectUnderTest.methodUnderTest(
mock(Handler.class).getClass().getName());
// ...
}
Create a public method where you will place the logic to fetch the newInstance of the class
ClassA objectClassA=createNewInstance(className);
likewise,and
public ClassA createInstance(String className){
return (ClassA) (Class.forName(className)).newInstance();
}
Now suppose we were creating an instance of classA inside of ClassB
then in TestClass of B, we can simply mock this createInstance method
doReturn(mockClassA).when(mockClassB).createInstance(className);

Test if another method was called

So I'm sure there is something like this out there but I have been searching for an hour and haven't found exactly what I am looking for. say I have a class that looks like this:
public class MyClass
{
public void myMethod(boolean shouldCallOtherMethod)
{
if(shouldCallOtherMethod)
{
otherMethod();
}
}
public void otherMethod()
{
System.out.println("Called");
}
}
How do I make something like this work?
#Test
public void shouldCallMethod()
{
MyClass myClass = new MyClass();
myClass.myMethod(true)
// verify myClass.otherMethod method was called
}
Using Mockito, you can do spying on real objects like this:
import org.junit.Test;
import static org.mockito.Mockito.*;
public class MyClassTest {
#Test
public void otherMethodShouldBeCalled() {
MyClass myClass = new MyClass();
MyClass spy = spy(myClass);
spy.myMethod(true);
verify(spy).otherMethod();
}
}
There are some gotchas, so take a look at the relevant documentation as well.
Suppose MokeysClass has a constructor declared like this, where Foo is some other class.
public MokeysClass(String name, int counter, Foo myFoo)
I would write my test like this.
#RunWith(MockitoJUnitRunner.class)
public class TestArray {
#Mock
private Foo mockMyFoo;
private String nameToInject = "Mokey";
private int counterToInject = 42;
#Spy
private MokeysClass toTest = new MokeysClass(nameToInject, counterToInject, mockMyFoo);
#Test
public void shouldCallMethod() {
toTest.myMethod(true);
verify(toTest).otherMethod();
}
}
so that I am explicitly stating which constructor to call when I create my test object, and what arguments to pass to it.
There are some reasons not to rely on #InjectMocks to do this step for me, particularly if the class being tested is more complex and has more than one constructor. Mockito chooses the constructor that has the most arguments, but if there are several constructors with the same number of arguments, Mockito could choose any of the constructors; that is, the behaviour is undefined.
Once Mockito has chosen a constructor, it checks whether that constructor can in fact be used for constructor injection. Constructor injection will not be used if
one or more of the parameters of the chosen constructor is a primitive type,
the type of one or more of the parameters of the chosen constructor is a final class,
the type of one or more of the parameters of the chosen constructor is a private class,
the only constructor of the class is the default constructor.
If any one of these conditions holds, for the constructor that Mockito chose, then constructor injection won’t be used. In this case, the class must have a default constructor, otherwise Mockito will throw an exception.
The complexity of the criteria which Mockito uses when choosing whether to apply constructor injection implies that adding or removing a constructor, or changing the parameters of a constructor, can make Mockito switch from using constructor injection to using setter and field injection; or from using setter and field injection to using constructor injection. This can occur even if the constructor that is changed is not the one that will be used for constructor injection.
As a result, any test that uses constructor injection is automatically quite brittle; in the sense that changes that are not directly related to the test itself can cause the test to fail. Such failures can be difficult to troubleshoot.
The #InjectMocks annotation was designed for use with frameworks such as Spring that do dependency injection; and for tests of classes that use Spring, it can be invaluable. But if dependency injection is not part of your class, I would strongly recommend avoiding #InjectMocks on account of its brittleness. You really want your test code to be as easy to maintain and to troubleshoot as your production code is.
This is not recommended, but you can spy real object :)
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.BDDMockito.verify;
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Spy
private MyClass sut; // System Under Test
#Test
public void shouldCallMethod() {
// when
sut.myMethod(true);
// then
verify(sut).otherMethod();
}
}
Result:
Tests Passed: 1 passed in 0,203 s
After changing code: sut.myMethod(false);
Wanted but not invoked:
sut.otherMethod();
-> at my.custom.MyClassTest.shouldCallMethod(MyClassTest.java:23)
Source: Spying on real objects
Magic version with constructor injection
#Mock
private LexAnalyzer lexAnalyzer;
#Spy
#InjectMocks
private SyntaxAnalyzer sut; // System Under Test
#Test
public void shouldCallMethod() {
// when
sut.myMethod(true);
// then
verify(sut).otherMethod();
}
SyntaxAnalyzer.java
public class SyntaxAnalyzer {
private final LexAnalyzer lexAnalyzer;
public SyntaxAnalyzer(LexAnalyzer lexAnalyzer) {
this.lexAnalyzer = lexAnalyzer;
}
...
Tested, works ;)
I think you want to look at Mock objects. You can create a mock of MyClass, then set expectations that otherMethod() is called when you call myMethod and fails if it was not called.
Here is a pretty good overview of them for java - http://www.scalatest.org/user_guide/testing_with_mock_objects
One other major benefit of using Mocks, you can avoid side affects, like logging to NSLog or hitting a web server or printing) in your test.

Testing a Static Methods Class had to be Changed to a Singleton For JUnit Testing

I have a static methods class, Utils, that is basically for utility methods, its used by almost every class. It does things like get files and other basic stuff. My tester went and changed this class to a singleton so that every class using Utils now has to call getInstance(). The reason was that he couldn't test certain things unless this was the case. It seems to me that this is wrong in some ways and that this could lead to issues.
public class Utils {
/**
* Singleton method to allow for easier testing.
* #return an instance of
*/
public synchronized static Utils getInstance() {
if (instance == null) {
instance = new Utils();
}
return instance;
}
public synchronized static void setInstance(Utils instance) {
Utils.instance = instance;
}
/** Singleton to make testing easier **/
private static Utils instance = null;
public static boolean checkOSTen() {
return getInstance()._checkOSTen();
}
private boolean _checkOSTen() {
boolean autoPair = false;
if (android.os.Build.VERSION.SDK_INT >= 10){
autoPair = true;
}
return autoPair;
}
}
By the way I have a very complex system of internal messaging that uses at least 7 threads to send messages and wanted to see if there is an impact of static method calls vs Singleton static method calls.
Is there another way to do testing other than this? Seems some Java reflection would get what you need.
Your tester probably finds this code difficult to test as they can't easily change the return value of android.os.Build.VERSION.SDK_INT, and therefore they can't easily test the different code paths that are used depending on this return value. By using an instance method they can use a mocking framework to fake the _checkOSTen method to return either true or false, depending on what they are trying to test.
Another way to do testing is to not use static methods such as these at all, and instead use class (perhaps called DeviceCapabilities) which will be injected via a setter or a constructor into every other class that requires knowledge of the version of the OS.
Then, your tester could easily pass instances of DeviceCapabilities to whichever class needed access to this information.
That said, at this stage in your build it may be too late to make a change like this so the change your tester has made is a reasonable compromise.

Java: Lazy Initializing Singleton

The pattern to create singletons seems to be something like:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance()
{
return instance;
}
}
However my problem is how do you Unit with a class like this if the Singleton Constructor does something that is not unit test friendly e.g. calls external service , jndi lookup etc.
I would think i could refactor it like:
public class Singleton {
private static Singleton instance;
private Singleton(){
}
public synchronized static Singleton getInstance()
{
if(instance == null)
instance = new Singleton();
return instance;
}
//for the unit tests
public static void setInstance(Singleton s)
{
instancce = s;
}
}
The problem now is that just for unit testability I have forced the getInstance to be synchronized so just for testing aspect it will have a negative impact on the real application. Is there a way around it, it seems any other sort of lazy initialization will not work because of the broken nature of double locking pattern in java.
You can use an enum as a Singleton
enum Singleton {
INSTANCE;
}
Say your singleton does something undesirable in unit tests, you can;
// in the unit test before using the Singleton, or any other global flag.
System.setProperty("unit.testing", "true");
Singleton.INSTANCE.doSomething();
enum Singleton {
INSTANCE;
{
if(Boolean.getBoolean("unit.testing")) {
// is unit testing.
} else {
// normal operation.
}
}
}
Note: there is no synchronised blocks or explicit lock needed. The INSTANCE will not be loaded until the .class is accessed and not initialised until a member is used. provided you only use Singleton.INSTANCE and not Singleton.class there won't be a problem with the value used to initialise changing later.
Edit: if you use just the Singleton.class this might not initialise the class. It doesn't in this example on Java 8 update 112.
public class ClassInitMain {
public static void main(String[] args) {
System.out.println("Printing a class reference");
Class clazz = Singleton.class;
System.out.println("clazz = " + clazz);
System.out.println("\nUsing an enum value");
Singleton instance = Singleton.INSTANCE;
}
static enum Singleton {
INSTANCE;
Singleton() {
System.out.println(getClass() + " initialised");
}
}
}
prints
Printing a class reference
clazz = class ClassInitMain$Singleton
Using an enum value
class ClassInitMain$Singleton initialised
You could use the Factory pattern to create the singleton, and switch implementations depending on evironment.
Or, avoid using the singleton pattern, and use Dependency Injection instead.
Double-checked locking is broken in every language, not just Java.
I tend to eschew singletons, but you can use the holder pattern just fine if you need them, as recommended in Josh Bloch's Effective Java:
public class Foo
{
static class Holder
{
static final Foo instance = new Foo();
}
public static Foo getInstance()
{
return Holder.instance;
}
private Foo()
{
}
// ...
}
EDIT: Repaired the reference.
You can dependency inject the singleton instance, override the getInstance() from the unit test code, use aspect oriented programming to intercept the method call and return a different object, or use a tool like jmockit which lets you mock pretty much anything, including statics, final classes, constructors, and all the stuff people normally say is "untestable."
One approach I've taken in legacy systems (where I wanted to make something testable with a minimal impact on the system's architecture) was to modify the factory methods (getInstance) to check a system property for an alternate implementation that I would instantiate instead. This was set to an alternate, mock object in the unit test suite.
As for the "double checked locking is broken" statement, that's not really true anymore, if you use the volatile keyword, and Java >= 1.5. It was broken (even with volatile) with 1.4 and earlier, but if you know your code will be run on only recent JVMs, I wouldn't worry about it. But I also wouldn't use a singleton anyway: having a DI/IOC container manage the lifecycle of the object would solve both of your problems (testability and synchronized accessor bottleneck) much more elegantly.
How about you lazy initialize in the build phase where you execute the unit tests. Then you change the code back to inline initialize before it's compiled for distribution.
Your production code is inline initialized, except during your tests. Perhaps this discrepancy btw production and testing code could introdude bugs, but which?
(Of course if this is a solution, we let a build phase + tool do the work. I see this facilitated with maven and dp4j).

Categories