5

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

4
  • Why are you running tests on your production machines? Commented Apr 6, 2013 at 17:02
  • @kashif, why don't you use dummy cache while running your tests? Commented Apr 6, 2013 at 18:55
  • @Alexander, the cache I am using above in my actual code is file system docs.djangoproject.com/en/dev/topics/cache/?from=olddocs/… . How can I specify another value for 'BACKEND' in 'default' cache while running my test cases and still make sure that the actual code in views.py accesses file system based? Commented Apr 6, 2013 at 19:03
  • @kashif, decided to answer, please, check. Commented Apr 6, 2013 at 19:26

1 Answer 1

15

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.

Sign up to request clarification or add additional context in comments.

4 Comments

docs.djangoproject.com/en/4.1/topics/testing/tools/… is the current version of that dead link - I added an edit to the answer - it should be approved soon.
Also, to add to the answer: dummy_cache is great if you want to turn caching off, if you want to actually test caching, I would recommend the local memory cache docs.djangoproject.com/en/4.1/topics/cache/…
Second link is broken.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.