Тестирование интеграции с Redis

Я начал использовать Redis в своем проекте с помощью библиотеки Jedis. Все работает нормально, но теперь у меня есть проблема, что мои функциональные тесты требуют, чтобы Redis был включен, чего я хочу избежать в своей непрерывной интеграции. Каков наилучший способ сделать это?

Ответ 1

Ниже приведено несколько вариантов тестирования функциональности/интеграции:

  • Просто запустите экземпляр redis на сервере CI. Все тесты будут отвечать за правильную очистку после выполнения.
  • Попробуйте каким-то образом управлять процессом redis, т.е. иметь некоторую оболочку script или задание на сервере CI, чтобы запустить/остановить ее до/после запуска тестов. По крайней мере, часть бремени установки/очистки удаляется из тестов, так как для каждой независимой сборки у вас будет независимая настройка redis.
  • Управление redis далее, используя некоторое решение в памяти, подобное тому, которое вы указываете для cassandra (если оно существует).

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

Вот аналогичный вопрос о mongodb. Ответ имеет ссылку на проект, который работает для второго варианта (контролирует процесс mongodb). Если вы следуете некоторым связанным ссылкам на Страница проекта там также называется nosql-unit. Этот, я думаю, пытается рассмотреть третий вариант. Я не использовал его, но похоже, что у него есть что-то для redis.

Ответ 2

Я реализовал простой redis встроенный бегун для Java: https://github.com/kstyrc/embedded-redis

В настоящее время он использует redis 2.6.14 для * nix и https://github.com/MSOpenTech/redis для Windows. Однако вы можете использовать класс RedisServer для запуска собственного запуска script.

Я планирую расширить реализацию для поддержки RedisConf (bind, slaveof, port, dbfilename и т.д.). После этого я загружу jar в clojars для mvn deps.

Ответ 3

Вы можете запустить сервер Redis на произвольном порту через командную строку: redis-server --port 7777. Итак, для целей тестирования интеграции вы можете запустить Redis на доступном (или случайном) порту, убедившись, что Jedis настроен на использование этого порта.

Таким образом, у вас есть "свежий" экземпляр Redis, который, как вы знаете, не будет конфликтовать с другими процессами, включая другие тестовые прогоны, которые происходят одновременно. Это как можно ближе к аналогу запуска встроенной базы данных для интеграции тестирования.

Для предварительной загрузки Redis с "консервированными данными" используйте переключатель --dbfilename <file>: redis-server --port 7777 --dbfilename test.rdb.

Ответ 4

попробуйте nosql-unit. Он поддерживает redis unit test с помощью java.

Я попробовал EmbeddedRedis и обнаружил, что многие интерфейсы Jedis не поддерживаются. Следовательно, использование EmbbededRedis не является хорошей идеей, особенно если вы используете какую-то расширенную функцию redis, например "конвейер".

Я предлагаю использовать ManagedRedis для unit test:

  • загрузите исходный код redis из redis.io в тестовый ресурс
  • создать redis-сервер в $(your-redis-dir)/src
  • напишите unit test с ManagedRedis, вот пример. Обратите внимание, что "REDIS_HOME" - это каталог, в котором загружен ваш код redis, ManagedRedis найдет redis-сервер в ${REDIS_HOME}/src
  • запустите вас unit test.

Ответ 5

Как @ksytrc упомянул в его ответ, я в основном использовал его решение. Он работал в в этом проекте. Вам просто нужно добавить зависимость embedded-redis.

        <dependency>
            <groupId>com.github.kstyrc</groupId>
            <artifactId>embedded-redis</artifactId>
            <version>0.6</version>
            <scope>test</scope>
        </dependency>

то в тестовом классе определите redisServer

RedisServer redisServer;

    @Before
    public void setUp() throws IOException {
        redisServer = new RedisServer();
        redisServer.start();
    }

Также определите application.yml со следующими учетными данными.

spring:
  redis:
    host: localhost
    port: 6379

Ответ 6

Лучший способ решить эту проблему - создать службу Spring, которая обрабатывает RedisTemplate. После этого я просто использую @MockBean для @MockBean над сервисом и абстрагирую отсутствие экземпляра Redis, работающего во время моих тестов.

За пример:

@Service
class RedisService {

    @Autowired
    private RedisTemplate<String, SomeClass> redisTemplate;

    SomeClass get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

}

И в интеграционном тесте:

class IntegrationTest {

    @MockBean
    private RedisService redisService;

    @Before
    public void setup() {
        SomeClass someClass= new SomeClass();
        when(redisService.get(anyString())).thenReturn(someClass);
    }


}