Reputation: 33
The unit test of a class is involved with a static method in a another class, say HelperClass
. HelperClass
has a singleton member. I used Junit
for the unit tests and Powermockito
to mock the singleton member. But I found that the behavior of the method of the singleton member can only be specified once.
//the class to be tested
class Activity {
public void enact() {
//some logic
String str = HelperClass.doSomething();
//some other logic
}
}
class HelperClass {
private static final singleton = Singleton.getInstance();
public static String doSomething() {
//some logic
AnObject obj;
try {
obj = singleton.doSomething();
} catch (Exception1 e) {
//Some other logic
throw new Exception2("Some message" + e.getMessage(), e);
}
String val = obj.doSomething();
return val;
}
}
class Singleton {
private Singleton instance = null;
private void Singleton() { /*some logic*/ }
public static Singleton getInstance() {
if (instance == null) {
Singleton();
}
return instance;
}
public String doSomething() throws Exception1 {
//some logic
}
}
My uint test goes like this
@RunWith(PowerMockRunner.class)
@PrepareForTest(Singleton.class)
class ActivityTest {
//some logic
private Activity activity;
@Before
public void setup() {
//some logic
PowerMockito.mockStatic(Singleton.class);
activity = new Activity();
}
@Test(expected = Exception2.class)
void test1() {
Singleton mockSingleton = mock(Singleton.class);
when(mockSingleton.doSomething()).thenThrow(new Exception1("Test Exception1"));
PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);
activity.enact();
}
@Test
void test2() {
Singleton mockSingleton = mock(Singleton.class);
when(mockSingleton.doSomething()).thenReturn("");
PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);
activity.enact();
}
}
But it does not work. Although I specify different behaviors of the doSomething()
of the mockSingleton
, the mockSingleton
still throws the Exception2
in test2
as it does in test1
. It seems that the behavior can only be specified once. Can somebody tell me how I can let the doSomething()
here have different behaviors?
Upvotes: 2
Views: 228
Reputation: 1163
You are calling Signleton.getInstance
only once - when HelperClass
is initialized. This way you always use the mock from your first test. To solve this, you can call getInstance
every time you need an instance of Singleton
.
Thus, the code for HelperClass
would be:
class HelperClass {
public static String doSomething() {
//some logic
AnObject obj;
try {
obj = Singleton.getInstance().doSomething();
} catch (Exception1 e) {
//Some other logic
throw new Exception2("Some message" + e.getMessage(), e);
}
String val = obj.doSomething();
return val;
}
}
This way, you will get the right mock on every run.
Upvotes: 1