@TestTemplate
public void whenHSettingOnTheSameKeys_EnsureReturnTypeIs1WhenKeysAreNew(Jedis jedis) {
assertEquals(1L, jedis.hset(HASH, FIELD_1, VALUE_1));
assertEquals(0L, jedis.hset(HASH, FIELD_1, VALUE_1));
}Ivan Ponomarev
![]() | Ivan Ponomarev
|

Remote Dictionary Server
In-memory key–value database
Different kinds of abstract data structures
Not open source since 2024 with OOS forks available, but it’s a separate story…
Twitter, AirBnB, Tinder, Yahoo, Adobe, Hulu, Amazon…
Really easy to use
Really high performant: 10000 max clients default value (compare with the default maximum for 100 for PostgreSQL)
Swiss army knife: caches, queues, atomic counters, distributed locks, semaphores, Bloom filters, etc etc etc

Price we pay: no ACID (only isolation) 
Testcontainers, of course!

(In fact, Redis is one of the first demo examples for Testcontainers ever)
Still, Testcontainers require Docker and some time to download and run the container.
Jedis-Mock requires Java only.
Sometimes we want to manage the reply:
imitate a system or network failure
give a deterministic answer for non-deterministic query
Sometimes we need to check the actual queries being sent

2017: Filipe Peliz Pinto Teixeira forked an abandoned POC repository.
2019: I tried to use it in my project and soon gave up
2021-now: actively developed by MIPT students under my supervision
2023: I have full rights for maintaing & publishig new versions

Known OSS dependents: Slack API client, dropwizard.io

Stable flow of incoming issues and requests.
180+ stars on GitHub — please give it a star!

Redis is written in C (155 KLOC of C code)

Redis/Valkey heavily relies on system calls and runs on Unix-like systems only.
Redis/Valkey uses a single thread to process all the requests (thus isolation).
|
|
Redis data type | Java data type |
HMAP | HashMap |
LIST | ArrayList |
SET | HashSet |
ZSET | TreeSet+HashMap |
Bit operations | BitSet |
java.net.ServerSocket
Each incoming client occupies a thread in CachedThreadPool
All the threads synchronize on a single lock before making changes
Blocking operations (like BLPOP) use wait/notify
Redis: 246 commands of varying popularity (Pareto 80/20 principle applies)
Jedis-mock: 166 commands supported (67% and the number is growing)

Redis: 246 commands of varying popularity (Pareto 80/20 princple applies)
Jedis-mock: 166 commands supported (67% and the number is growing)

Redis COMMAND command lists all the supported commands (currently 225 of them)
Classes annotated @Command(<COMMAND_NAME>) implement commands in Jedis-mock

Comparison testing
@TestTemplate
public void whenHSettingOnTheSameKeys_EnsureReturnTypeIs1WhenKeysAreNew(Jedis jedis) {
assertEquals(1L, jedis.hset(HASH, FIELD_1, VALUE_1));
assertEquals(0L, jedis.hset(HASH, FIELD_1, VALUE_1));
}Comparison testing

Written in Tcl
test {INCR over 32bit value} {
r set novar 17179869184
r incr novar
} {17179869185}3932 tests in 200 Tcl scripts
we only run a subset of them, gradually increasing the number of successful "native" tests
SET key1 stringvalue // puts a string to key1
HSET key2 subkey1 avalue // puts a hashmap to key2
GET key1 // returns stringvalue
GET key2 // error: WRONGTYPE
MGET key1 key2 // ????LPOP mylist // returns the first element
// or null, if the list is empty
BLPOP mylist 1 // returns the first element
// or waits for it for 1 second maximum
BLPOP mylist 0 // ????How closely a test mock should mock 'the real thing'?
Are those "bugs" Jedis-mock problems or Redis spec problems / possible source of bad practices?
Some day we will successfully run 100% of the tests. What happens when somebody finds a bug in Jedis-mock?