asm*_*ier 3 java jmockit default-constructor
我想模拟默认构造函数,java.util.date
因此它不会构造一个Date
表示创建时间的对象,但始终是相同的Date
对象(在我2010年12月31日的示例中).我尝试用JMockit
和执行此操作JUnit
,但在执行下面的测试时,输出始终是Thu Jan 01 01:00:00 CET 1970
.那我的模拟有Date()
什么问题?
import java.util.Date;
import org.junit.*;
import mockit.*;
public class AppTest {
@Before
public void setUp() {
Mockit.setUpMocks(MockedDate.class);
}
@After
public void tearDown() {
Mockit.tearDownMocks();
}
@Test
public void testDate() {
Date today=new Date();
System.out.println(today.toString());
}
@MockClass(realClass=Date.class)
public static class MockedDate {
@Mock
public void $init() {
// Now should be always 31.12.2010!
new Date(110,11,31); //110 = 2010! 11 = December! This is sick!
}
}
}
Run Code Online (Sandbox Code Playgroud)
asm*_*ier 10
al nik的答案对我来说是一个很好的暗示.最好是模拟System
类而不是Date
类来生成假时间.我自己的解决方案最终只是模拟System.currentTimeMillis()
方法(此方法由Date()
内部调用).
JMockit 1.5及更高版本
new MockUp<System>(){
@Mock
public long currentTimeMillis() {
// Now is always 11/11/2011
Date fake = new Date(111,10,11);
return fake.getTime();
}
};
Run Code Online (Sandbox Code Playgroud)
JMockit 1.4及更早版本
@MockClass(realClass = System.class)
public static class MockedSystem {
@Mock
public long currentTimeMillis() {
// Now is always 11/11/2011
Date fake = new Date(111,10,11);
return fake.getTime();
}
}
Run Code Online (Sandbox Code Playgroud)
正如测试驱动书中所建议的那样,在java类中使用SystemTime抽象是一种很好的做法.替换方法调用(System#currentTimeMillis和Calendar#getInstance)并使用静态方法调用直接构造(new Date()),如:
long time = SystemTime.asMillis();
Calendar calendar = SystemTime.asCalendar();
Date date = SystemTime.asDate();
Run Code Online (Sandbox Code Playgroud)
假冒时间你只需要修改SystemTime类返回的内容.
SystemTime使用默认委托给System.currentTimeMillis()的TimeSource接口
public interface TimeSource {
long millis();
}
Run Code Online (Sandbox Code Playgroud)
可配置的SystemTime实现可能是这样的
public class SystemTime {
private static final TimeSource defaultSrc =
new TimeSource() {
public long millis() {
return System.currentTimeMillis();
}
};
private static TimeSource source = null;
public static long asMillis() {
return getTimeSource().millis();
}
public static Date asDate() {
return new Date(asMillis());
}
public static void reset() {
setTimeSource(null);
}
public static void setTimeSource(TimeSource source) {
SystemTime.source = source;
}
private static TimeSource getTimeSource() {
return (source != null ? source : defaultSrc);
}
}
Run Code Online (Sandbox Code Playgroud)
并伪造你刚刚做的返回时间
@Test
public void clockReturnsFakedTimeInMilliseconds() throws Exception {
final long fakeTime = 123456790L;
SystemTime.setTimeSource(new TimeSource() {
public long millis() {
return fakeTime;
}
});
long clock = SystemTime.asMillis();
assertEquals("Should return fake time", fakeTime, clock);
}
Run Code Online (Sandbox Code Playgroud)
Joda-Time库简化了Java中日期的使用,并为您提供开箱即用的功能