| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Design, Quality, Testing > Юнит тесты календаря |
| Автор: LSD 10.5.2012, 13:20 |
| Есть класс который реализует некоторую логику по работе с календарем. Вся логика по работе с датами инкапсулирована в этом классе. Возник вопрос, как тестировать функциональность в разные моменты времени, т.е. грубо говоря надо подменить результат System.currentTimeMillis(). Можно конечно сделать в классе кастомный метод getTime() и в тестах подменять результат его работы, но выглядит как-то криво. Может есть более другие методы? |
| Автор: Старовъръ 10.5.2012, 13:36 |
| Можно или использовать какие-то свои утилитные классы что-то вроде http://sonar.jtalks.org/resource/index/605, создавать в продакшн коде обычный, а в тестах подменять на http://sonar.jtalks.org/resource/index/661, а можно просто выносить статику в другой метод этого же класса, делать его package-private и создавать spy(), в котором подменять этот метод в SUT. Оба способа предусматривают, что скорей всего видимость какого-то члена класса будет минимум package-private и он будет открыт скорей всего только для тестов, но это небольшой trade-off за тестируемость. К тому же такой член класса можно пометить как @VisibleForTesting (взять из guava или написать свою документирующую аннотацию). |
| Автор: Stolzen 10.5.2012, 13:52 |
| Первое, что приходит в голову - вынести получение времени в отдельную зависимость и мокать ее (как и написал Старовъръ) А второе - это использовать PowerMock, он статику позволяет мокать. Как именно он это делает, я не знаю, ни разу не пользовался, обычно первым способом обхожусь. |
| Автор: Старовъръ 11.5.2012, 16:56 |
| PowerMock в нелегаси системах, наверно, не лучший выбор. Если интересно все-таки легковесное решение, то лучше все-таки выделить отдельный метод в классе типа getTime() и сделать Mockito.spy(sut) и дальше замокать его. |
| Автор: LSD 11.5.2012, 16:58 |
Почему? |
| Автор: Старовъръ 13.5.2012, 14:26 |
|
| Автор: Stolzen 22.6.2012, 23:19 |
| Вот и наткнулся самолично на описанные грабли - при использовании PowerMock JaCoCo/EclEmma не могут получать данные о тестовом покрытии из-за вмешательств первого в байт-код классов. Проблему решил запуском этих тестов через Cobertura, но осадочек остался. |
| Автор: LSD 12.7.2012, 10:56 |
| У нас PowerMock прекрасно работает, и не пришлось извращаться с time provider. |
| Автор: powerOn 28.8.2012, 19:29 |
| а я бы лучше выбрал тайм провайдер. Использовать power mock значит создавать прецедент, по которму он сможет применяться для аналогичных случаев (мокать не мокируемое), где на самом деле нужен рефакторинг. Да и в литературе советуют создавать "анти-коррупционный" слой, если API платформы уныл - а такое не редкость. Вот тут: http://www.growing-object-oriented-software.com/ пример с датами как раз разбирают в одной из глав. |