我怎么能模仿JodaTime的实际约会?

时间:2010-12-15 19:41:56

标签: 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", 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

4 个答案:

答案 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接口,我仍然感到惊讶的是它不属于其中一个常见库。我有两个我经常使用的实现,WallClockStoppedClock(这对于使用固定时间的测试非常有用)。

答案 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实例,并使用它来填充yearmonth

答案 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...
}