How to mock a redis client in Python?

15,565

Solution 1

Think you can use side effect to set and get value in a local dict

data = {}
def set(key, val):
    data[key] = val

def get(key):
    return data[key]

mock_redis_set.side_effect = set
mock_redis_get.side_effect = get

not tested this but I think it should do what you want

Solution 2

If you want something more complete, you can try fakeredis

@patch("redis.Redis", return_value=fakeredis.FakeStrictRedis())
def test_something():
....
Share:
15,565
Houman
Author by

Houman

I'm a thinker and a dreamer. Love pets but don't have any. I'm a passionate tech entrepreneur.

Updated on June 08, 2022

Comments

  • Houman
    Houman almost 2 years

    I just found that a bunch of unit tests are failing, due a developer hasn't mocked out the dependency to a redis client within the test. I'm trying to give a hand in this matter but have difficulties myself.

    The method writes to a redis client:

    redis_client = get_redis_client()
    redis_client.set('temp-facility-data', cPickle.dumps(df))
    

    Later in the assert the result is retrieved:

    res = cPickle.loads(get_redis_client().get('temp-facility-data'))
    expected = pd.Series([set([1, 2, 3, 4, 5])], index=[1])
    assert_series_equal(res.variation_pks, expected)
    

    I managed to patch the redis client's get() and set() successfully.

    @mock.patch('redis.StrictRedis.get')
    @mock.patch('redis.StrictRedis.set')
    def test_identical(self, mock_redis_set, mock_redis_get):
        mock_redis_get.return_value = ???
        f2 = deepcopy(self.f)
        f3 = deepcopy(self.f)
        f2.pk = 2
        f3.pk = 3
        self.one_row(f2, f3)
    

    but I don't know how to set the return_value of get() to what the set() would set in the code, so that the test would pass.

    Right now this line fails the test:

    res = cPickle.loads(get_redis_client().get('temp-facility-data'))
    TypeError: must be string, not MagicMock
    

    Any advice please?