Java 如何模拟JodaTime的实际日期?
我想测试这个方法:Java 如何模拟JodaTime的实际日期?,java,testing,mocking,jodatime,Java,Testing,Mocking,Jodatime,我想测试这个方法: public FirmOrder findActiveByModelColor(ModelColor modelColor) { Query query = em.createQuery("FROM FirmOrder fo WHERE fo.modelColor = :modelColor AND fo.year = :year AND fo.month = :month"); query.setParameter("modelColor", modelCol
public FirmOrder findActiveByModelColor(ModelColor modelColor) {
Query query = em.createQuery("FROM FirmOrder fo WHERE fo.modelColor = :modelColor AND fo.year = :year AND fo.month = :month");
query.setParameter("modelColor", modelColor);
query.setParameter("year", new DateTime().year().get());
query.setParameter("month", new DateTime().monthOfYear().get());
return (FirmOrder) query.getSingleResult();
}
但是我需要DateTime().year().get()
和DateTime().dayOfMonth().get()
始终返回相同的日期
tks然后您需要定义一个
时钟
接口,并将其注入到您的类中
public interface Clock {
DateTime getCurrentDateTime();
}
然后:
然后,您的测试可以注入始终返回固定时间的时钟的实现(例如,使用模拟框架)
我在自己的东西中经常使用时钟
接口,但我仍然感到惊讶的是,它并不是公共库的一部分。我有两个我经常使用的实现,wallcock
和stoppedcock
(这对使用固定时间的测试很有用)。如果您不能按照skaffman的建议添加factory对象,您可以使用。如果使用预期模拟API,这很容易:
@Test
public void findActiveByModelColor()
{
new NonStrictExpectations()
{
@Cascading DateTime dt;
{
dt.year().get(); result = 2010;
dt.monthOfYear().get(); result = 12;
}
};
FirmOrder fo = testedObject.findActiveByModelColor(modelColor);
// asserts...
}
@测试
public void findActiveByModelColor()
{
新的非严格测量()
{
@级联日期时间dt;
{
dt.year().get();结果=2010;
dt.monthOfYear().get();结果=12;
}
};
FirmOrder fo=testedObject.findActiveByModelColor(modelColor);
//断言。。。
}
看起来唯一的选择是使用回答功能发布此评论:
代码的以下部分可能导致难以检测的错误:
query.setParameter("year", new DateTime().year().get());
query.setParameter("month", new DateTime().monthOfYear().get());
让我们假设今天是2011年的最后一天,这部分代码称为新年前1纳秒,第一个语句需要1纳秒以上的时间才能完成。这意味着该年将设置为2011年,但月份设置为1,但最好设置为2011/12或2012/1
虽然从统计上看,这不太可能发生,但从逻辑上讲,这是可以发生的:)
您应该创建一个DateTime实例,并使用它来填充年
和月
,所以,像这样使用日期时间
(或java.util.Date
)的代码总是不好的?那么使用Apache Commons电子邮件API的代码呢,它实例化了一个SimpleMail
对象并在其上调用send()
?是坏代码吗?为什么?我喜欢你的主意。但我有一个问题想问Clock#getCurrentDateTime()
将返回当前的JodaTime#DateTime
,这非常好。但是,我需要将当前日期时间与美国东部时间下午4点进行比较。在我的代码中,我有一个fourPM=newdatetime(current.getYear(),current.getMonthOfYear(),current.getDayOfMonth(),16,0,0,DateTimeZone.forID(“EST”)哈利:你需要问一个新问题,我只是创建一个新问题。请帮助如何使用clock.now()
Joda Time提供了此接口。默认实现是可以的,这并不是OP的真正答案,但我投了更高的票,因为更多的人需要意识到这个问题。考虑到许多企业商店(和家庭设施)在晚上的非工作时间(如晚上11:30)进行编译,这个bug实际上非常常见,而且令人讨厌。这通常更微妙,但这就是为什么在另一个答案中提到的停止时钟是一个好主意。一个很好的评论,我想要两次喜欢它。在测试断言之后,也许你会想用setCurrentMillisSystem
将它重置回system。这个API修改了一个全局变量,因此必须避免使用它。@多态性pTo你有其他建议吗?在现代Java中正确执行此操作的方法是传入一个Java.time.Clock实例并在测试中模拟它。
query.setParameter("year", new DateTime().year().get());
query.setParameter("month", new DateTime().monthOfYear().get());