具有最终类System和静态方法currentTimeMillis的PowerMock

时间:2015-01-29 16:27:53

标签: java methods static final powermock

我不明白为什么PowerMock这样做。

测试类

public class Testimpl {
    public long test() {
        long a = System.currentTimeMillis();
        System.out.println("2: " + a);
        return a;
    }
}

JUNIT级

import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
public class TestimplTest {

    @InjectMocks
    Testimpl testimpl;

    @Before
    public void setUp() throws Exception {
        initMocks(testimpl);
        PowerMockito.mockStatic(System.class);
    }

    @Test
    public void test() {
        PowerMockito.when(System.currentTimeMillis()).thenReturn(12345l);
        System.out.println("1: " + System.currentTimeMillis());
        long a = testimpl.test();
        System.out.println("3: " + a);
    }

}

输出:

  

1:12345

     

2:1422547577101

     

3:1422547577101

为什么在jUnit TestimplTest类中正确使用PowerMock / Mockito而不在测试的Testimpl类中?

我使用jUnit 4.11和Mockito 1.9.5与PowerMock 1.6.1。

感谢您的帮助。

2 个答案:

答案 0 :(得分:7)

注释@PrepareForTest必须让您的测试类正确模拟System.currentTimeMillis()方法。来源及有关的更多信息:PowerMock wiki

使用@PrepareForTest注释中的正确类@PrepareForTest(Testimpl.class),我有预期的输出:

  

1:12345
  2:12345
  3:12345

答案 1 :(得分:0)

另一个答案对我不起作用,但这是一个基于Maksim Dmitriev's gist的很好的例子。

诀窍是引入类似SystemUtils.java的包装器类,该包装器类提供对System方法的公共静态访问器。然后在其上运行spy并模拟该方法。

以下是示例:

FileUtils.java

package sample.com.sample_app;

import android.support.annotation.NonNull;

public class FileUtils {
    @NonNull
    public static String generateName() {
        return Long.toString(SystemUtils.currentTimeMillis());
    }
}

FileUtilsTest.java

package sample.com.sample_app;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static junit.framework.TestCase.assertEquals;

@RunWith(PowerMockRunner.class)
@PrepareForTest({SystemUtils.class})
public class FileUtilsTest {

    @Test
    public void generateName() {
        PowerMockito.spy(SystemUtils.class);
        PowerMockito.when(SystemUtils.currentTimeMillis()).thenReturn(100L);

        String name = FileUtils.generateName();
        assertEquals("100", name);
    }
}

SystemUtils.java

package sample.com.sample_app;

public class SystemUtils {

    private SystemUtils() {
        throw new AssertionError();
    }

    public static long currentTimeMillis() {
        return System.currentTimeMillis();
    }
}