我想测试一下这个方法:
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
答案 0 :(得分:52)
如果您无法按照skaffman的建议添加工厂对象,则可以使用DateTimeUtils.setCurrentMillisFixed()
。
答案 1 :(得分:15)
然后你需要定义一个Clock
接口,并将其注入你的类
public interface Clock {
DateTime getCurrentDateTime();
}
然后:
Clock clock;
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", clock.getCurrentDateTime().year().get());
query.setParameter("month", clock.getCurrentDateTime().dayOfMonth().get());
return (FirmOrder) query.getSingleResult();
}
然后,您的测试可以注入Clock
的实现(例如使用模拟框架),该实现始终返回固定时间。
我在自己的东西中经常使用Clock
接口,我仍然感到惊讶的是它不属于其中一个常见库。我有两个我经常使用的实现,WallClock
和StoppedClock
(这对于使用固定时间的测试非常有用)。
答案 2 :(得分:4)
看起来唯一的选择是使用答案功能发布此评论:
您的代码的以下部分可能导致难以检测的错误:
query.setParameter("year", new DateTime().year().get());
query.setParameter("month", new DateTime().monthOfYear().get());
让我们假装今天是2011年的最后一天,这部分代码在新的一年之前被称为1纳秒,并且第一个声明需要超过1纳秒才能完成。这意味着年份将设置为2011年,但月份将设置为1,但最好是2011/12或2012/1。
虽然从统计上来说这种情况不太可能发生,但从逻辑上讲它可能会发生:)
您应该创建一个DateTime实例,并使用它来填充year
和month
。
答案 3 :(得分:1)
如果使用JMockit Expectations模拟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...
}