如何使用JMockit模拟Date类的默认构造函数?
我想模拟 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!
}
}
}
I want to mock the default constructor of java.util.date
so it does not construct
a Date
object representing the time when it was created, but always the same Date
object (in my example below 31 Dec 2010). I tried doing this with JMockit
and JUnit
, but when executing my test below, the output is always Thu Jan 01 01:00:00 CET 1970
. So what is wrong with my mock of 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!
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
al nik 的回答对我来说是一个很好的提示。最好模拟
System
类而不是Date
类来生成假时间。我自己的解决方案最终只是简单地模拟 System.currentTimeMillis() 方法(该方法由Date() 内部调用)。
JMockit 1.5 及更高版本
JMockit 1.4 及更早版本
al nik's answer was a good hint for me. It is better to mock the
System
class instead of theDate
class to generate a fake time. My own solution in the end was simply to mock theSystem.currentTimeMillis()
method (this method is called byDate()
internally).JMockit 1.5 and later
JMockit 1.4 and earlier
正如测试驱动一书中所建议的,在您的应用程序中使用 SystemTime 抽象是一种很好的做法。 java 类。
将方法调用(System#currentTimeMillis 和 Calendar#getInstance)和直接构造(new Date())替换为静态方法调用,例如:
要伪造时间,您只需修改 SystemTime 类返回的内容即可。
SystemTime 使用 TimeSource 接口,默认情况下委托给 System.currentTimeMillis()
一个可配置的 SystemTime 实现可能是这样的,
并且要伪造返回的时间,您只需执行
Joda-Time 库 简化了 Java 中的日期处理,并为您提供了开箱即用的功能
As suggested in the Test Driven book it's good practice to use a SystemTime abstraction in your java classes.
Replace your method calls (System#currentTimeMillis and Calendar#getInstance) and direct construction (new Date()) with static method calls like:
To fake the time you just need to modify what's returned by your SystemTime class.
SystemTime use a TimeSource interface that by default delegates to System.currentTimeMillis()
a configurable SystemTime implementation could be something like this
and to fake the returned time you simply do
Joda-Time library simplifies working with dates in Java and offers you something like this out of the box
您模拟了构造函数,并在内部创建了一个 Date 实例(与构造的实例无关),然后将其丢弃。由于默认构造函数是模拟出来的,因此日期不会初始化为当前时间,因此您得到的时间为零(代表 1970-01-01)。
要修改返回的日期,您需要使用神奇的“it”属性,如下所示:
You mocked the constructor, and inside you made an instance of Date (that has nothing to do with the one constructed) and just threw it away. Since the default constructor is mocked out, date is not initialized to the current time, and so you get the time of zero (which represents 1970-01-01).
To modify the returned date you need to use a magic "it" attribute, like so:
这是一个基于 @asmaier 的精彩答案的完整 JUnit 示例:
当使用 Maven 时,在
pom.xml
中按如下方式配置 JMockit:And here's a complete JUnit example based on @asmaier's great answer:
When using Maven, configure JMockit as follows in
pom.xml
: