Android 单元测试:模拟 System.currentTimeMillis()

Android Unit Test: mocking System.currentTimeMillis()

我正在学习如何编写单元测试,并且 运行 遇到了一些问题。

基本上,我的方法是根据系统时钟设置闹钟,所以在测试中我想模拟系统class。我试过 this answer 说的。所以这是我的测试:

@RunWith(PowerMockRunner.class)
public class ApplicationBackgroundUtilsTest {
    @Mock
    private Context context;

    @Mock
    private AlarmManager alarmManager;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void registerAlarmManagerTest() {
        PowerMockito.mockStatic(System.class);
        when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn(alarmManager);
        BDDMockito.given(System.currentTimeMillis()).willReturn(0L);

        ApplicationBackgroundUtils.getInstance().registerAlarmManager(context);

        verify(alarmManager, times(1)).set(eq(AlarmManager.RTC_WAKEUP), eq(120L), any(PendingIntent.class));

    }

所以对于这段代码,我期望 System.currentTimeMillis() 总是 return 0 但我得到的是:

Comparison Failure: 
Expected :alarmManager.set(0, 120, <any>);
Actual   :alarmManager.set(0, 1524564129683, null);

所以我猜系统的模拟不起作用。

我该怎么做?

原来我只是错过了 @PrepareForTest(ApplicationBackgroundUtils.class) 在 class 声明之前。

我认为它准备 class 进行测试以使用模拟,但如果有人想进一步澄清,欢迎。

编辑:感谢 pavithraCS:

@PrepareForTest annotation is used by powermock to prepare the specified class or classes for testing. It will perform bytecode manipualtions to the given class to enable mocking of final classes, static methods.. etc.

powermock 使用

@PrepareForTest 注释来准备指定的 class 或 classes 进行测试。它将对给定的 class 执行字节码操作,以启用对最终 classes、静态方法等的模拟