[ACCEPTED]-Different Singleton instances with JUnit tests-singleton
I assume you have a private static field 6 within your singleton class to store the 5 initialized instance.
If you do not want 4 to modify your code, you can define a teardown 3 method which run after every test, and in 2 this method you set this static field to 1 null via reflection as seen here.
Don't use a singleton.
Specifically, the 13 only difference between a singleton and 12 a global variable is that the singleton 11 tries to enforce a single instance (by making 10 the constructor private, for example).
Instead, make 9 the constructor public and write tests using 8 new instances. In your actual program, use 7 getInstance()
to get the canonical global instance (or 6 use an IOC container).
And remember that 5 singletons are pathological liars.
If you're still too comfortable with the 4 idea of a Singleton, instead of making the 3 constructor public you can add a public 2 (and static) factory method to create instances 1 in a way that can't be used by accident, e.g.:
public static MyClass TEST_CreateInstance() {
return new MyClass();
}
You can add a method to destroy the singleton, for 6 example destroyMe(); where you deinitialize 5 everything and set the instance of the singleton 4 to null.
public void destroyMe(){
this.instance = null;
//-- other stuff to turn it off.
}
I will leave synchronization problems 3 though ;)
But why do you need to re-initialize 2 your singleton for each test? It should 1 not differ based on the concept of the singleton.
Spring provides the DirtiesContext annotation for this 5 particular use case where you need new instances 4 of the singleton beans for each testcase. It 3 basically creates a new application context 2 for each testcase/testclass which has this 1 annotation applied.
I highly recommend moving away from Singletons as a design 13 pattern, and using Singleton as a scope 12 (Dependency Injection). This would simply 11 make your problem go away.
But assuming 10 you are stuck in the world of Singletons, then 9 you have a few options depending on if you 8 are testing the Singleton or the dependency.
If 7 you are testing the dependant item then 6 you can mock the Singleton using PowerMock and JMockIt. See 5 my previous post about mocking Runtime.getRuntime for 4 instructions on how to go about this.
If 3 you are testing the Singleton then you need 2 to relax the rules on construction, or give 1 the Singleton a "Reset" method.
generally beware of singletons, most often 6 they are evil, bad design and tend to represent 5 big yucky global variables (which is bad 4 for maintenance).
still to get tests in place 3 first you can do:
static setInstance(...){ //package visibility or in difficult cases you have to use public
instance = ...;
}
as said this is more a 2 workaround. so get first tests place, but 1 then refactor away from singleton pattern.
Singleton instance needs to be passed to 4 SUT by test itself - that way you create 3 singleton (and destroy) for each test. Adopting 2 IoC and mocking framework, like Mockito, would 1 render this approach almost trivial.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.