总结:我正在尝试创建一个简单的模拟来替换redis。从代码中可以明显看出我要做的事情。简短的版本是,模拟不起作用 - 它仍然是redis和创建密钥。
tests.py:
from django.test import TestCase
import mock
from redis_mock.simple_redis_mock import redisMockGetRedis, redisMockFlushDB
from account.util import get_redis
class SimpleTest(TestCase):
def setUp(self):
redisMockFlushDB()
@mock.patch("account.util.get_redis", redisMockGetRedis)
def test_redis(self):
key = "hello123"
value = "world123"
r = get_redis()
r.set(key, value)
value2 = r.get(key)
self.assertEqual(value, value2)
util.py:
from django.test import TestCase
import mock
from redis_mock.simple_redis_mock import redisMockGetRedis, redisMockFlushDB
from account.util import get_redis
class SimpleTest(TestCase):
def setUp(self):
redisMockFlushDB()
@mock.patch("account.util.get_redis", redisMockGetRedis)
def test_redis(self):
key = "hello123"
value = "world123"
r = get_redis()
r.set(key, value)
value2 = r.get(key)
self.assertEqual(value, value2)
simple_redis_mock.py:
import redis
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DEFAULT_DB = 0
def get_redis():
print "account.util.get_redis"
return redis.StrictRedis(
REDIS_HOST,
REDIS_PORT,
REDIS_DEFAULT_DB
)
现在,我期望的是,当我运行测试时,没有设置redis键。这是实际发生的事情:
"""
A simple mock for Redis. Just mocks set, get and expire commands.
"""
class SimpleRedisMockDB:
db = {}
def redisMockFlushDB():
"""
Helper function to flush the RedisMock db between test runs
"""
print "redisMockFlushDB"
SimpleRedisMock.db = {}
class SimpleRedisMock:
def get(self, key):
val = None
try:
val = SimpleRedisMockDB.db[key]
except:
pass
print "SimpleRedisMock get(" + str(key) + "):" + str(val)
return val
def set(self, key, val):
print "SimpleRedisMock set(" + str(key) + "," + str(val) +")"
SimpleRedisMockDB.db[key] = val
def expire(self, key):
pass
def redisMockGetRedis():
print "redisMockGetRedis"
return SimpleRedisMock()
简单的问题:为什么mock.patch不按照我的期望做什么?
答案 0 :(得分:9)
答案 1 :(得分:7)
修补程序仅模拟您修补它的位置中的对象。一小段示例代码应该有助于解释发生了什么。
from mock import Mock, patch
import unittest
from patch_code import anotherfunc, thefunc
print 'Function imported', thefunc
class SomeTest(unittest.TestCase):
@patch('patch_code.thefunc', Mock())
def test_method(self):
anotherfunc()
print 'Inside test method', thefunc
if __name__ == '__main__':
unittest.main()
正在测试的代码只有两个功能:
def thefunc():
pass
def anotherfunc():
print 'Inside code under test', thefunc
运行该测试会得到以下输出
Function imported <function thefunc at 0xb740e614>
Inside code under test <Mock id='3071597132'>
Inside test method <function thefunc at 0xb740e614>
你可以清楚地看到补丁模拟'thefunc'的唯一地方是在被测试的代码中。
如果你想测试函数get_redis
而不会产生任何副作用,那么你应该模拟account.util.redis.StrictRedis
并声明它是用正确的参数调用的。
如果您要测试使用 get_redis
的功能,那么您应该模拟get_redis
并导入使用get_redis的函数,然后调用那个< / strong>在您的测试中起作用。
答案 2 :(得分:2)
尝试导入get_redis
,而不是导入import util and call util.get_redis()
。