unit-redis-ness
- A fully in-memory redis implementation in typescript to aid unit testing of redis-based nodejs applications. Brought to you by yours truly!
Initially inspired by mini-redis but ulitimately adapted from the very well-designed ClauDB
The reason? I 100% agree with Antonio
- "Just For Fun!"
But also because I had need of redis for unit testing on my last project, where we used bull. But I found it difficult to unit test the queue processors without spinning up a fully functional redis implementation. Since we use CI/CD it was not practical to have a redis farm just for testing. Instead I embedded a klunky precursor to this project and never felt good about it.
Now I feel good.
Well, better.
This project is released under the MIT license. It includes work from some fine projects such as:
- fengari - The Lua VM written in JS ES6 for Node and the browser
- resp - An implementation of the Redis Encoding and Serialization Protocol for Node.js.
- redis-sorted-set - A JavaScript implementation of Redis' Sorted Sets (Converted to typescript)
Code Coverage Report
Mochawesome Report
The full unit-test suite is tested against redis v5.0.5 with each release
Code Documentation
Repository
Recent activity
As of 1.0.11 2020-01-22
- Install fengari direct from git to get latest code
- Implemented HGETALL, ZSCORE, ZRANGEBYSCORE, and PEXPIRE
- Implemented LUA BIT library
- Validated test suite against redis 5.0.5
- Validated against BULL
As of 1.0.10
unit-redis-ness has a more-or-less fully functional embedded LUA instance (fengari), which includes a rudimentary LUA bit library, and it can process complex scripts generated by Bull. Many thanks to the developer(s) of flua who helped to demystify fengari and LUA in general.
Unfortunately the code became spaghetti during refactoring for SUBSCRIBE, PUBLISH, DISCARD, and blocking commands BRPOP, BLPOP, and BRPOPLPUSH so a wholesale refactoring is underway.
The current suite of 287 tests has been validated against an actual redis 5.0.5 instance.
How to use
Have a look at the skeleton project test-unit-redisness included with the distribution. Or read along here:
npm install -D unit-redis-ness mocha @types/node chai net source-map-support ts-node typescript @types/chai @types/mocha
Configure ./test/mocha.opts like so (if you don't already have it configured):
--require source-map-support/register
--require ts-node/register
--full-trace
--bail
--timeout=5000
test/**/*.test.ts test/*.test.ts
Use this template:
import { RespServer, sendCommand } from 'unit-redis-ness';
import { expect } from 'chai';
import 'mocha';
import * as net from 'net';
process.env.REDIS_HOST = '127.0.0.1';
process.env.REDIS_PORT = '6378';
const respServer = new RespServer();
const client: net.Socket = new net.Socket();
before((done) => {
respServer.on('ready', () => {
console.log(`The redis server is ready to test your application`);
done();
});
respServer.start();
});
after((done) => {
respServer.on('closed', () => {
console.log(`The redis server has shut down`);
done();
});
respServer.stop();
});
describe('Some test suite', () => {
it('should start the redis server and allow a connection', async () => {
const response = await sendCommand(client, ['PING']);
expect(response).to.be.a('string');
expect(response).to.equal('PONG');
});
})
Current State
As of 1.0.4 unit-redis-ness includes embedded fengari, which means that LUA is now available.
All of the current test suite has been validated against a live redis instance (except for tests involving MAX_SAFE_INTEGER and MIN_SAFE_INTEGER - these are only 53 bits in unit-redis-ness)
As of v1.0.9, unit-redis-net supports 8 "server" commands:
- ping
- echo
- time
- quit
- info
- publish
- subscribe
- unsubscribe
Plus these "database" commands:
- get
- set
- exists
- del
- hset
- hget
- incr
- decr
- incrby
- decrby
- client (partial)
- select
- dbsize
- sadd
- scard
- sismember
- smembers
- smove
- zadd
- zrange
- zcount
- zcard
- zincrby
- zrem
- type
- script
- eval
- evalsha
- expire
- rename
- flushdb
- flushall
- keys
- mset
- llen
- lindex
- rpop
- rpush
- move
- getset
- lpop
- lpush
- lset
- lrange
- lrem
- zrank
- ltrim
- mget
- randomkey
- renamenx
- rpoplpush
- sdiff
- setnx
- sinter
- sinterstore
- srem
- sunion
- sunionstore
- ttl
- brpop
- blpop
- brpoplpush
- exec
- multi
- discard
Todo (to complete v1.0.0 command set)
- sort
- spop
- srandmember
Probably Won't do
- auth
- bgsave
- monitor
- save
- shutdown
- slaveof
- anything that involves replication, clustering, or persistence to disk
This is, after all, intended as a unit test tool
Future plans
Time permitting, I expect to:
- implement the full redis command set up to 2.6.x (maybe later)
- embed lua (completed)
- circle back around to validate that Bull can be thoroughly tested