不能使模拟的单例方法在不同的测试用例中表现不同
Can not make the mocked singleton's method behave differently in different test cases
class 的单元测试涉及另一个class 中的静态方法,比如说HelperClass
。 HelperClass
有一个单例成员。我使用 Junit
进行单元测试,使用 Powermockito
模拟单例成员。但是我发现单例成员的方法的行为只能指定一次
//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
}
}
我的 uint 测试是这样的
@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();
}
}
但是没有用。虽然我指定了 mockSingleton
的 doSomething()
的不同行为,但 mockSingleton
仍然像在 test1
中一样在 test2
中抛出 Exception2
。似乎只能指定一次行为。有人能告诉我如何让这里的 doSomething()
有不同的行为吗?
您只调用了一次 Signleton.getInstance
- 当 HelperClass
初始化时。这样您就可以始终使用第一次测试中的模拟。要解决这个问题,您可以在每次需要 Singleton
.
的实例时调用 getInstance
因此,HelperClass
的代码将是:
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;
}
}
这样,您将在每个 运行 上获得正确的模拟。
class 的单元测试涉及另一个class 中的静态方法,比如说HelperClass
。 HelperClass
有一个单例成员。我使用 Junit
进行单元测试,使用 Powermockito
模拟单例成员。但是我发现单例成员的方法的行为只能指定一次
//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
}
}
我的 uint 测试是这样的
@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();
}
}
但是没有用。虽然我指定了 mockSingleton
的 doSomething()
的不同行为,但 mockSingleton
仍然像在 test1
中一样在 test2
中抛出 Exception2
。似乎只能指定一次行为。有人能告诉我如何让这里的 doSomething()
有不同的行为吗?
您只调用了一次 Signleton.getInstance
- 当 HelperClass
初始化时。这样您就可以始终使用第一次测试中的模拟。要解决这个问题,您可以在每次需要 Singleton
.
getInstance
因此,HelperClass
的代码将是:
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;
}
}
这样,您将在每个 运行 上获得正确的模拟。