Java 带有最终类系统和静态方法currentTimeMillis的PowerMock
我不明白PowerMock为什么这样做 测试班Java 带有最终类系统和静态方法currentTimeMillis的PowerMock,java,methods,static,final,powermock,Java,Methods,Static,Final,Powermock,我不明白PowerMock为什么这样做 测试班 public class Testimpl { public long test() { long a = System.currentTimeMillis(); System.out.println("2: " + a); return a; } } 初中班 import static org.mockito.MockitoAnnotations.initMocks; import
public class Testimpl {
public long test() {
long a = System.currentTimeMillis();
System.out.println("2: " + a);
return a;
}
}
初中班
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:142254777101
3:142254777101
为什么PowerMock/Mockito在jUnit TestimplTest类中正确工作而在测试的Testimpl类中不正确工作
我在PowerMock 1.6.1中使用JUnit4.11和Mockito 1.9.5
感谢您的帮助。注释
@PrepareForTest
必须有经过测试的类才能正确模拟系统.currentTimeMillis()
方法。来源和更多信息:
使用@PrepareForTest
注释中的正确类:@PrepareForTest(Testimpl.class)
,我得到了预期的输出:
1:123452:12345
3:12345
另一个答案不适用于我,但这里有一个基于的好例子 诀窍是引入一个包装类,如
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());
}
}
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);
}
}
package sample.com.sample_app;
public class SystemUtils {
private SystemUtils() {
throw new AssertionError();
}
public static long currentTimeMillis() {
return System.currentTimeMillis();
}
}
FileUtilsTest.java
:
package sample.com.sample_app;
import android.support.annotation.NonNull;
public class FileUtils {
@NonNull
public static String generateName() {
return Long.toString(SystemUtils.currentTimeMillis());
}
}
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);
}
}
package sample.com.sample_app;
public class SystemUtils {
private SystemUtils() {
throw new AssertionError();
}
public static long currentTimeMillis() {
return System.currentTimeMillis();
}
}
SystemUtils.java
:
package sample.com.sample_app;
import android.support.annotation.NonNull;
public class FileUtils {
@NonNull
public static String generateName() {
return Long.toString(SystemUtils.currentTimeMillis());
}
}
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);
}
}
package sample.com.sample_app;
public class SystemUtils {
private SystemUtils() {
throw new AssertionError();
}
public static long currentTimeMillis() {
return System.currentTimeMillis();
}
}
太棒了。有同样的问题。为我工作。@TheLion,你有没有设法模仿
系统。currentTimeMillis
?我了解到,默认情况下,PowerMock使用其MockClassLoader加载所有类。类加载器加载并修改除系统类以外的所有类。所以看起来我们不能模仿Java静态方法,必须编写包装器。我写了一个,它是有效的:。但事实并非如此