This week in Causes Tech, engineer and brewmaster Sam Merritt talks about mock_redis, an open-source tool built here at Causes. For the code, check out the Causes github. For the opportunity to write the code, join our team!
We here at Causes are pretty big fans of Redis. We use it to track the results of A/B testing with Modesty, our internal health-tracking app uses Redis as its sole datastore, and we’ve used the Redis-backed Resque in an app or two. However, it has been painful to write tests around our Redis-using code.
We started off by just talking to a real live Redis during tests. This worked okay, but developers would sometimes get test failures due to stale data in Redis. It didn’t happen too often, but they happened often enough to be annoying; it was time for Plan B.
Plan B seemed like a surefire win: call flushdb() before starting a test run, thus guaranteeing you a blank slate to scribble on. This sounded great, but then developers would sometimes get their manual testing screwed up by an automated test run; the automated tests would come in and blow away all the data in Redis.
Plan C: same as Plan B, but development uses Redis database 0 while tests use Redis database 1. It was a definite improvement over plan B, but Plan C fails horribly when one test run starts while another is running. Those of you who are thinking “like on the CI machine?” get ten bonus points.) Generally it’s the first test run that gets wiped out, but sometimes they engage in mutual destruction, and there is much wailing and gnashing of teeth.
That’s why we wrote mock_redis. It’s a Redis mock, so you can use it like you would a real Redis object. It’s just a Ruby object, so it’s confined to your Ruby process. Other test runs can’t step on your Redis data, and you can’t step on theirs. The best part is, mock_redis behaves just like a real Redis does in your tests. Transactions? Yep. Hashes, lists, and sorted sets? Check. Multiple databases? Got it. Working expiration? Yes indeed.