我有一个测试用例,它模拟java.lang.System
类的静态方法:
@Test
fun `getLocalTime()`() {
// Arrange
val staticMock = Mockito.mockStatic(System::class.java)
Mockito.`when`(System.currentTimeMillis()).thenReturn(1000L)
// Action
val res = deviceTimeProvider.getLocalTime()
// Assert
Truth.assertThat(res).isEqualTo(1000L)
staticMock.close()
}
但是当我运行测试时,出现此错误:
org.mockito.exceptions.base.MockitoException:无法执行 模拟java.lang.System的静态方法以避免干扰 类加载导致无限循环的原因
为什么会这样?如何模拟java.lang.System
类的方法?
答案 0 :(得分:2)
虽然Mockito自3.4.0版本以来就允许模拟静态方法,但不允许模拟Thread
和System
静态方法,请参见this comment on github
最后请注意,Mockito禁止模拟System(和Thread)的静态方法。这些方法在同一个线程中进行了类加载。有时,我们可能会在类加载中添加工具,以暂时禁用其中的静态模拟,从而对这些类进行模拟,在此我们还需要禁用其强化属性。但是,您可以轻松地模拟Instant.now()。
答案 1 :(得分:1)
如果您喜欢丑陋的解决方案,您仍然可以使用PowerMockito
来模拟System
@PrepareForTest(System.class)
public class TestCase {
@BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.currentTimeMillis()).thenReturn(1000L);
}
...
但是如果可能的话,我会避免模拟System类。您仍然可以将其包装在方法中并模拟该方法。
答案 2 :(得分:0)
在 Mockito 的帮助下模拟 java.lang.System
类的静态方法。
ISystem.java
public interface ISystem {
String getProperty(String name);
Long getCurrentTimeInMillis();
}
2- 创建 ISystem 接口的实现类,即 ISystemImpl.java
public class ISystemImpl implements ISystem {
@Override
public String getProperty(final String name) {
return System.getProperty(name);
}
@Override
public Long getCurrentTimeInMillis() {
return System.currentTimeMillis();
}
}
3- 在 Isystem.java
类中使用 DeviceTimeProvider.java
。
public class DeviceTimeProvider {
@NonNull private final ISystem mISystem;
public DeviceTimeProvider(ISystem iSystem){
mIsystem = iSystem;
}
public Long getLocalTime(){
return mIsystem.getCurrentTimeInMillis()
}
}
4- 现在终于模拟了测试类中的 ISystem 接口。
public class DeviceTimeProviderTest {
private ISystem mISystem;
private DeviceTimeProvider sut;
@Before
public setup(){
mIsystem = mockito.mock(ISystem.class)
sut = new DeviceTimeProvider(mISystem);
}
@Test
public void getDeviceLocalTime(){
Long expectedTime = 1000L;
mockit.when(mISystem.getCurrentTimeInMillis()).thenReturn(expectedTime);
Long actualTime = sut.getLocalTime();
Assert.assertEquals(actualTime, expectedTime);
}
}
输出