Как смоделировать LocalCache в модульном тестировании с помощью Mockito - PullRequest
1 голос
/ 03 мая 2019

Мой базовый класс использует библиотеку Java, отвечающую за аудит. Эта библиотека использует шаблон Builder для извлечения объектов из моего проекта Java для операций аудита ( Вставка в несколько таблиц путем создания ключей самостоятельно. ) Эта библиотека использует com.google.common.cache для управления значениями кэша. то есть Строка и Значение. LoadingCache<String, Long>

пример Пример использования моего проекта библиотеки

auditOperation = LibraryAuditBuilder.builder()
//some param
.build()
LibraryAuditingService.process(auditOperation);

Мое базовое приложение и библиотека работают на базе данных Oracle, а мои модульные тесты используют базу данных HSQL. Учитывая все необходимые скрипты в @Before, я бы хотел выполнить мой код для выполнения модульного теста.

@Before метод

@Before
    public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
//create db scrips and other declarations
}

Я уже пробовал 2 подхода

1) Создал LoadingCache и поместил в него примеры значений, чтобы UnitTest мог использовать его позже при выполнении.

longLoadingCache.put("4028eeb0-1d2d-daba-011d-2e36e4b2110e",(long)203);
longLoadingCache.put("4028ee14-24b4-5221-0124-b47bbb1d1232",(long)102);

2) @Mock объект LoadingCache и значения в нем для последующего использования в тестах

when(longLoadingCache.get("4028eeb0-1d2d-daba-011d-2e36e4b2110e")).thenReturn((long)203);     
when(longLoadingCache.get("4028ee14-24b4-5221-0124-b47bbb1d1232")).thenReturn((long)102);

Токовый выход с вышеупомянутым подходом

- com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key 4028ee14-24b4-5221-0124-b47bbb1d1232.

Итак, мой вопрос, Как я могу передать / опровергнуть значения Cache, чтобы UnitTests не нужно было искать значения в классе Library.

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Хотя ответ @Lukasz был совершенно верным, но требовал гораздо больше усилий. Потратив несколько часов, я смог создать более простое решение для этой проблемы. Вместо @Mock ing LocalCache я могу просто @Mock class (Library library) предоставить значения кэша, так как они были статическими значениями, и нам все равно, как сама библиотека их получает. что-то вроде следующего

 busAuditOperationDao = mock(BusAuditOperationDao.class);
 busAuditProcessDao = mock(BusAuditProcessDao.class);

в @Before методе я могу указать любые значения, которые я хочу, которые будут использоваться в @test классах

when(busAuditOperationDao.getAuditOperationIdFromGuid("4028eeb0-1d2d-daba-011d-2e36e4b2110e")).thenReturn((long) 102);
when(busAuditProcessDao.getAuditProcessIdFromGuid("4028ee14-24b4-5221-0124-b47bbb1d1232")).thenReturn((long)203);
1 голос
/ 03 мая 2019

Подумайте о создании собственного фасольного компонента, обертывающего стороннюю библиотеку (например, AuditProcessor). Когда фасад вводится с помощью @Autowire или @Inject, вы можете легко смоделировать его в тестовом коде и проверить, правильно ли использовался ваш упаковочный фасад (читай: библиотека). Если вы не доверяете библиотеке, вы можете провести модульное тестирование фасада упаковки и всех угловых случаев в изолированной среде без HSQL. Если вам нужен еще больший контроль, вы можете ввести интерфейс (например, IAuditProcessor) и создать фиктивную реализацию, которая будет @Autowired в тесте с использованием профилей Spring.

Подведем итог:

  • Тест на основе HSQL должен проверить, вызывается ли фасад, когда ожидается, и с правильными аргументами
  • угловые случаи / кэширование должны тестироваться отдельно в изолированных тестовых случаях без контекста HSQL / Spring
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...