You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DRF测试中用Fakeredis模拟Django缓存并验证缓存状态?

使用Fakeredis模拟Django缓存并在DRF测试中验证缓存状态

问题背景

我正在用Fakeredis模拟Django测试,相关配置及代码如下:

settings.py 配置

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6382",
        "TIMEOUT": env.int("CACHE_TIMEOUT", default=2 * 60 * 60),
        "OPTIONS": {
            "CONNECTION_POOL_KWARGS": {"connection_class": FakeConnection},
        },
    }
}

views.py 代码

视图通过from django.core.cache import cache使用缓存:

from django.core.cache import cache
from rest_framework import viewsets, response

class MyViewSet(viewsets.GenericViewSet):
    
    @action(methods=["GET"], detail=False)
    def my_view(self, request):
        if my_data := cache.get("my_key"):
            # 缓存命中逻辑
            pass
        else:
            # 计算逻辑
            my_data = {"value": "calculated_result"}  # 示例计算结果
            cache.set("my_key", my_data)
        return response.Response(my_data)

当前测试代码

现在想在DRF测试中验证缓存已被设置,且第二次调用接口时直接从缓存取值,不执行计算逻辑。当前tests.py代码:

from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status

class MyTestCase(APITestCase):
    def test_my_view(self):
        response = self.client.get(reverse("my_view"))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual()  # 想要检查缓存是否已设置

请问是否有办法用Fakeredis模拟Django缓存并验证缓存中已存入对应值?


解决方案

完全可以通过Fakeredis模拟缓存并验证状态,直接利用Django的cache对象检查缓存值,同时借助mock工具验证缓存命中逻辑。

1. 验证缓存已被设置

直接在测试中调用cache.get()检查目标key的存在性和值的正确性:

from django.core.cache import cache
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status

class MyTestCase(APITestCase):
    def test_my_view_cache_set(self):
        # 第一次调用接口,触发计算并写入缓存
        response = self.client.get(reverse("my_view"))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        
        # 检查缓存中是否存在目标key,且值匹配预期
        cached_data = cache.get("my_key")
        self.assertIsNotNone(cached_data)
        self.assertEqual(cached_data, {"value": "calculated_result"})

2. 验证第二次调用走缓存(跳过计算逻辑)

将视图中的计算逻辑抽为独立函数,用unittest.mock拦截该函数,验证第二次调用时不会执行计算:

from unittest.mock import patch
from django.core.cache import cache
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status

class MyTestCase(APITestCase):
    def test_my_view_cache_hit(self):
        # 首次调用,初始化缓存
        self.client.get(reverse("my_view"))
        
        # Mock计算逻辑函数(假设计算逻辑在myapp.utils下的calculate_data函数中)
        with patch("myapp.utils.calculate_data") as mock_calculate:
            # 第二次调用接口
            response = self.client.get(reverse("my_view"))
            
            # 验证计算函数未被调用(说明走了缓存)
            mock_calculate.assert_not_called()
            
            # 验证返回数据与缓存一致
            cached_data = cache.get("my_key")
            self.assertEqual(response.data, cached_data)

注意事项

  • Django测试框架会在每个测试方法执行后自动清空缓存,无需手动清理
  • 确保测试中使用的cache对象与视图中一致(默认使用default缓存配置)
  • 若计算逻辑直接写在视图内,建议抽为独立函数,方便mock验证

内容的提问来源于stack exchange,提问作者Headmaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:47:17