Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python django mock cache

In my settings.py , I have specified my cache as :

 CACHES = {
    'default': {
     ......
   }
}

In my views.py, I have

import requests
from django.core.cache import cache, get_cache

def aview():
    #check cache
    if not get_cache('default').get('key'):
        #make request and save in cache
        result = request.get('some_url')
        get_cache('default').set('key', result)
        return result
    else:
        return get_cache('default').get('key')

Now in my tests.py, I have been able to mock requests.get('aurl'), so that makes sure that no external requests are made.

But the test code still hits the cache and gets/sets from it. So if my prod has already set the cache, then test is failing because it gets the data from same cache. Or if I run my tests first, then the test case is setting the cache with test data and I see that same reflected when I run prod website.

How can I mock the calls to

get_cache('default').set('key', result) 

and

get_cache('default').get('key') 

so that the set call does not sets the real cache ( return None?) and get does not return anything in actual cache.

Please provide me with code sample to how to get this done.

Here is how I have mocked my requests.get

def test_get_aview(self):
    with mock.patch('requests.get') as mymock:
        mymock.side_effect = (lambda url: MOCKED_DATA[url])

What code can I put after this to make it work? I tried something like

class MockCacheValue(mock.MagicMock):
    def get(self, key):
        print 'here'
        return None
    def set(self, key, value):
        print 'here 2'
        pass

def test_get_aview(self):
        with mock.patch('requests.get') as mymock:
            mymock.side_effect = (lambda url: MOCKED_DATA[url])
            mock.patch('django.core.cache.get_cache', new=MockCacheValue)

but it does not work and putting a print statement inside get/set above does not print anything giving me an idea that its not mocked properly

like image 276
kk1957 Avatar asked Dec 16 '22 12:12

kk1957


1 Answers

I think you should use dummy cache while running tests by:

  • overriding settings in test cases, see docs

  • checking what cache backend to use while testing right in settings.py:

      CACHES = ...
      if 'test' in sys.argv:
          CACHES['default'] = {'BACKEND': 'django.core.cache.backends.dummy.DummyCache',}
    
  • having a separate settings.py for testing

  • mocking, see good article on how to do it

Hope that helps.

like image 55
alecxe Avatar answered Dec 18 '22 12:12

alecxe