I want to test the behavior of a singleton class with 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, which invoke 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 it this way, I always get the IllegalStateException
in the second test because instance != null
.
How can I run several tests involving init
in one test class?
Putting testGetInstanceSunnyDay
and testGetInstanceRainyDay
in 2 separate classes solves the problem, but I'm wondering if there is a better solution.
Fundamentally singletons are hard to test, precisely because of this sort of thing. You could add a clearStateForTesting
method:
static void clearStateForTesting() {
instance = null;
}
... but I'd suggest that you avoid the singleton pattern in the first place, if possible.
Also note that your singleton implementation isn't thread-safe at the moment. There are significantly better implementations if you really need to use a singleton.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With