Я начал использовать Redis в своем проекте с помощью библиотеки Jedis. Все работает нормально, но теперь у меня есть проблема, что мои функциональные тесты требуют, чтобы Redis был включен, чего я хочу избежать в своей непрерывной интеграции. Каков наилучший способ сделать это?
Тестирование интеграции с 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);
}
}