我对Python很陌生,并且很难解决如何在单元测试中模拟补丁API调用的问题。 仅供参考,我正在使用Python 2.7并使用nosetest来满足我的单元测试需求。
我有以下模块(myRedis.py),我想进行单元测试:
import logging
import redis
redispool = None
class myRedis(object):
def __init__(self, redisHost, redisPort, redisDBNum):
if not redisPort.isdigit():
raise TypeError('Exception: Expected int for redisPort')
if not redisDBNum.isdigit():
raise TypeError('Exception: Expected int for redisDBNum')
self._redis_instance = None
self._redishost = redisHost
self._redisport = redisPort
self._redisdb = redisDBNum
global redispool
redispool = redis.ConnectionPool(host=self._redishost,
port=self._redisport,
db=self._redisdb)
def redis_connect(self):
LOGGER.info('Connecting Redis client to %s:%s:%s', self._redishost,
self._redisport, self._redisdb)
self._redis_instance = redis.StrictRedis(connection_pool=redispool)
def write_redis(self, key, value):
retval = self._redis_instance.set(key, value)
LOGGER.info('Writing data to redis (%s, %s). Retval=%s', key, value, retval)
return retval
def read_redis(self, key):
retval = self._redis_instance.get(key)
LOGGER.info('Reading data from redis: key=%s. Retval=%s', key, retval)
return retval
就单元测试而言,到目前为止我有以下内容。
from nose.tools import *
import mock
from myRedis import myRedis
def setup():
pass
def teardown():
pass
@mock.patch('redis.StrictRedis')
def test_mock_redis_StrictRedis(mock_conn_pool):
mock_conn_pool.return_value = True
assert(True)
def test_myRedis():
assert_raises(TypeError, myRedis,
'test', '1234', 'a11')
assert_raises(TypeError, myRedis,
'test', 'a1234', '11')
myRedisObj = myRedis('localhost', '8888', '11')
assert_equal(myRedisObj._redishost, 'localhost')
assert_equal(myRedisObj._redisport, '8888')
assert_equal(myRedisObj._redisdb, '11')
myRedisObj.redis_connect()
#oclRedis.read_redis('test')
#oclRedis.write_redis('test', 'test')
我能够毫无问题地修补redis.StrictRedis()调用。但是我如何修补redis的'get()和set()调用,因为它们是在对象上调用的(myRedis.py中的_redis_instance)。我尝试了几个不同版本的@ mock.patch.object,但这对我不起作用。寻求一些指导。
提前致谢。
答案 0 :(得分:2)
你应该修补的不是你对象的实际调用,而是实际调用这些调用的对象本身。
在你的代码中,它将成为:
from nose.tools import *
import mock
import unittest
from red import myRedis
def setup():
pass
def teardown():
pass
@mock.patch('redis.StrictRedis')
def test_mock_redis_StrictRedis(mock_conn_pool):
mock_conn_pool.return_value = True
assert(True)
def test_myRedis_wrong_args():
assert_raises(TypeError, myRedis,
'test', '1234', 'a11')
assert_raises(TypeError, myRedis,
'test', 'a1234', '11')
def test_myRedis_ok():
myRedisObj = myRedis('localhost', '8888', '11')
assert_equal(myRedisObj._redishost, 'localhost')
assert_equal(myRedisObj._redisport, '8888')
assert_equal(myRedisObj._redisdb, '11')
@mock.patch('redis.StrictRedis.set')
def test_myRedis_write(mock_strict_redis_set):
mock_strict_redis_set.return_value = {}
myRedisObj = myRedis('localhost', '8888', '11')
redis_connect = myRedisObj.redis_connect()
connect = myRedisObj.write_redis('1', '2')
assert connect == {}
如您所见,我修改了您的测试以一次测试一件事。这是您通常希望做的事情,以避免副作用并保证测试隔离。
请考虑查看文档:{{3}}
最后缩进是Python中的关键,考虑在你的代码片段中进行适当的缩进