Ответ 1
Если вы не можете добавить объект factory, как было предложено skaffman, вы можете использовать DateTimeUtils.setCurrentMillisFixed()
.
Я хочу протестировать этот метод:
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()
, чтобы всегда возвращать ту же дату
ТКС
Если вы не можете добавить объект factory, как было предложено skaffman, вы можете использовать DateTimeUtils.setCurrentMillisFixed()
.
Затем вам нужно определить интерфейс 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
(что полезно для тестов, использующих фиксированное время).
Похоже, единственный вариант - использовать функцию ответа, чтобы опубликовать этот комментарий:
Следующая часть вашего кода может привести к ошибкам, которые трудно обнаружить:
query.setParameter("year", new DateTime().year().get());
query.setParameter("month", new DateTime().monthOfYear().get());
Предположим, что сегодня это последний день 2011 года, и эта часть кода называется 1 nano секундой до нового года и что первый оператор занимает более 1 nano секунды для завершения. Это означает, что год будет установлен на 2011 год, а на месяц до 1, но он должен был быть лучшим либо до 2011/12, либо в 2012 году.
Хотя это статистически очень маловероятно, но логически это может произойти:)
Вы должны создать один экземпляр DateTime и использовать его для заполнения как year
, так и month
.
Это легко, если использовать JMockit Ожидания насмешливого 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...
}