How to test single games in one test class?

I want to test the behavior of a singleton class with the following methods:

public class SomeSingleton { private final static int DEFAULT_VALUE1 = ...; private final static int DEFAULT_VALUE2 = ...; private static SomeSingleton instance; public static void init(int value1, int value2) { if (instance != null) { throw new IllegalStateException("SomeSingleton already initialized"); } instance = new SomeSingleton(value1, value2); } public static getInstance() { if (instance == null) { init(DEFAULT_VALUE1, DEFAULT_VALUE2); } return instance; } } 

And then I have a test class with several test methods that call init several times:

 @RunWith(PowerMockRunner.class) @PrepareForTest(SomeSingleton.class) public class SomeSingletonTest { @Test public void testGetInstanceSunnyDay() { [...] SomeSingleton.init(...); [...] SomeSingleton.getInstance(); [...] } @Test public void testGetInstanceRainyDay() { [...] SomeSingleton.init(...); // IllegalStateException [...] SomeSingleton.getInstance(); [...] } } 

When I do this like this, I always get IllegalStateException in the second test, because instance != null .

How to run multiple tests involving init in one test class?

Putting testGetInstanceSunnyDay and testGetInstanceRainyDay in 2 separate classes solves the problem, but I wonder if there is a better solution.

+4
source share
3 answers

Although I agree with John, another option is to use ReflectionTestUtils or generally reflection to set the instance field to null . Knowing that it can be fragile if the field name changes.

+2
source

In essence, singletones are hard to verify, precisely because of these kinds of things. You can add the clearStateForTesting method:

 static void clearStateForTesting() { instance = null; } 

... but I would suggest that you avoid a singleton pattern, if possible.

Also note that your singleton implementation is not thread safe at the moment. There are significantly better implementations if you really need to use singleton.

+5
source

Given that this is a Singleton, the init method does not make sense as a public method. Make it private and use only getInstance in your unit tests.

0
source

All Articles