为了线程安全,并且提高加载效率,单例模式的一种写法是使用静态内部类来实现,如下所示:
public class Singleton {
private Singleton() {
}
private static class SingletonInstance {
private static final Singleton instance = new Singleton();
private SingletonInstance() {
}
}
public static Singleton getInstance() {
return SingletonInstance.instance;
}
public int power(int number) {
return number * number;
}
}
Singleton类被加载时,静态内部类SingletonInstance并不会立即实例化,而是等到外部调用getInstance方法时才会实例化,这样避免了没有调用该类时也实例化一个对象,提高加载效率,节省内存。
另外,SingletonInstance是静态类,只会在第一次加载时初始化,这样由JVM自身机制保证了线程的安全性。
那么如何对这种实现方式进行模拟呢?比如我们想要在某个类中调用单例类的power方法,测试时想要模拟power方法,而不是真正执行。我们首先写个单例类的帮助类,如下:
public class SingletonHelper {
public int getPowerValue(int a) {
return Singleton.getInstance().power(a);
}
}
测试类如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Singleton.class})
public class SingletonHelperTest {
private SingletonHelper singletonHelper;
@Mock
private Singleton singleton;
@Before
public void setUp() throws Exception {
singletonHelper = new SingletonHelper();
PowerMockito.mockStatic(Singleton.class);
PowerMockito.when(Singleton.getInstance()).thenReturn(singleton);
}
@Test
public void testGetPowerValue() {
when(singleton.power(anyInt())).thenReturn(10);
assertEquals(10, singletonHelper.getPowerValue(3));
}
}
从上述代码中可以看出,就是利用模拟静态方法的方式来进行模拟。
网友评论