Spring Boot 2 - Тестирование @Cacheable с помощью Mockito для метода без аргументов не работает

У меня есть приложение, использующее Spring Boot 2. Я хотел бы протестировать метод с @Cacheable (Spring Cache) на нем. Я сделал простой пример, чтобы показать идею:

@Service
public class KeyService {

    @Cacheable("keyCache")
    public String getKey() {
        return "fakeKey";
    }
}

И тестовый класс:

@RunWith(SpringRunner.class)
@SpringBootTest
public class KeyServiceTest {

    @Autowired
    private KeyService keyService;

    @Test
    public void shouldReturnTheSameKey() {

        Mockito.when(keyService.getKey()).thenReturn("key1", "key2");

        String firstCall = keyService.getKey();
        assertEquals("key1", firstCall);

        String secondCall = keyService.getKey();
        assertEquals("key1", secondCall);
    }

    @EnableCaching
    @Configuration
    static class KeyServiceConfig {

        @Bean
        KeyService keyService() {
            return Mockito.mock(KeyService.class);
        }

        @Bean
        CacheManager cacheManager() {
            return new ConcurrentMapCacheManager("keyCache");
        }
    }
}

Пример выше не работает. Но если я изменю метод getKey() для получения параметра:

@Service
public class KeyService {

    @Cacheable("keyCache")
    public String getKey(String param) {
        return "fakeKey";
    }
}

И проведите рефакторинг теста, чтобы учесть это изменение, тест работает успешно:

@RunWith(SpringRunner.class)
@SpringBootTest
public class KeyServiceTest {

    @Autowired
    private KeyService keyService;

    @Test
    public void shouldReturnTheSameKey() {

        Mockito.when(keyService.getKey(Mockito.anyString())).thenReturn("key1", "key2");

        String firstCall = keyService.getKey("xyz");
        assertEquals("key1", firstCall);

        String secondCall = keyService.getKey("xyz");
        assertEquals("key1", secondCall);
    }

    @EnableCaching
    @Configuration
    static class KeyServiceConfig { //The same code as shown above }
}

Вы, ребята, знаете об этой проблеме?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
5 359
2

Ответы 2

Интересно, не возникла ли у вас проблема со стратегией генерации ключей по умолчанию: весенняя документация. Кажется, в этом большая разница между ними. Он меняет то, что он использует для ключа, хотя я думаю, что и то, и другое должно работать.

поиск в кэше выполняется с использованием в качестве ключа параметров метода. Это означает, что вам нужен ключ для методов, у которых нет параметров. Попробуйте этот @Cacheable(value = "keyCache", key = "#root.methodName")

Другие вопросы по теме